Udacity - Self-Driving Car NanoDegree

Dean Webb - Vehicle Detection & Tracking Pipeline

In this project, your goal is to write a software pipeline to detect vehicles in a video (start with the test_video.mp4 and later implement on full project_video.mp4), but the main output or product we want you to create is a detailed writeup of the project. Check out the writeup template for this project and use it as a starting point for creating your own writeup.

Project Goals:

The goals / steps of this project are the following:

  • Perform a Histogram of Oriented Gradients (HOG) feature extraction on a labeled training set of images and train a classifier Linear SVM classifier
  • Optionally, you can also apply a color transform and append binned color features, as well as histograms of color, to your HOG feature vector.
  • Note: for those first two steps don't forget to normalize your features and randomize a selection for training and testing.
  • Implement a sliding-window technique and use your trained classifier to search for vehicles in images.
  • Run your pipeline on a video stream (start with the test_video.mp4 and later implement on full project_video.mp4) and create a heat map of recurring detections frame by frame to reject outliers and follow detected vehicles.
  • Estimate a bounding box for vehicles detected.

Here are links to the labeled data for vehicle and non-vehicle examples to train your classifier. These example images come from a combination of the GTI vehicle image database, the KITTI vision benchmark suite, and examples extracted from the project video itself. You are welcome and encouraged to take advantage of the recently released Udacity labeled dataset to augment your training data.

Some example images for testing your pipeline on single frames are located in the test_images folder. To help the reviewer examine your work, please save examples of the output from each stage of your pipeline in the folder called ouput_images, and include them in your writeup for the project by describing what each image shows. The video called project_video.mp4 is the video your pipeline should work well on.

Dataset - Load Data and Extract Features

In [1]:
%matplotlib inline
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
import numpy as np
import cv2
import glob
from PIL import Image
import time
import os
import pickle
from skimage.feature import hog
from sklearn.svm import LinearSVC
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
In [2]:
## Dataset Parameters ##
LABELS_CSV = 'FILL_LATER.csv'
TRAINING_DATASET_DIRECTORY = 'training_set/'
PIPELINE_SETUP_DIRECTORY = 'pipeline_setup_images/'
WORKING_DIRECTORY = 'data/'
NON_VEHICLES_TOKEN = 'non-vehicles'
dataset_path = "{}{}{}{}".format(WORKING_DIRECTORY, TRAINING_DATASET_DIRECTORY,'**/', '*.png')
DATACACHE_DIRECTORY = os.path.join(WORKING_DIRECTORY, 'datacache/')

## Image Processing ##
DEFAULT_LENGTH, DEFAULT_WIDTH, DEFAULT_DEPTH = (64, 64, 3)
if DEFAULT_DEPTH > 1:
    DEFAULT_RESOLUTION = (DEFAULT_LENGTH, DEFAULT_WIDTH, DEFAULT_DEPTH)
else:
    DEFAULT_RESOLUTION = (DEFAULT_LENGTH, DEFAULT_WIDTH)

## Feature Extraction Parameters ##
# Spatial Binning
SPATIAL = 32
BIN_SPATIAL_SIZE = (SPATIAL, SPATIAL)
# Color Histogram
HIST_NBINS = 128
COLOR_SPACE = 'HSV'
# HOG Parameters
HOG_ORIENTATIONS = 9
HOG_PIXELS_PER_CELL = 8
HOG_CELLS_PER_BLOCK = 2
HOG_CHANNEL = 'ALL' # Can be 0, 1, 2, or "ALL"

# SVC Parameters
VALIDATION_PORTION = .3
N_PREDICTIONS = 100
In [3]:
# Define a function to scale .PNG and JPEG Files both to 0 to 1 
def normalize_pixels(img):
    max_pixel_value = np.max(img)
    if max_pixel_value > 1.0:
        img = np.copy(np.multiply(img, 1.0 / 255.0)).astype(np.float64) 
    return img

# Define a function to scale .PNG and JPEG Files both to 0 to 1 
def denormalize_pixels(img):
    max_pixel_value = np.max(img)
    if max_pixel_value <= 1.0:
        img = np.copy(np.multiply(img, 255.0)).astype(np.float64) 
    return img
In [4]:
# Define a function to compute binned color features  
def bin_spatial(img, size=BIN_SPATIAL_SIZE):
    color1 = cv2.resize(img[:,:,0], size).ravel()
    color2 = cv2.resize(img[:,:,1], size).ravel()
    color3 = cv2.resize(img[:,:,2], size).ravel()
    return np.hstack((color1, color2, color3)) 
In [5]:
# Define a function to compute color histogram features  
def color_hist(img, nbins=HIST_NBINS):
    # Compute the histogram of the color channels separately
    channel1_hist = np.histogram(img[:,:,0], bins=nbins)
    channel2_hist = np.histogram(img[:,:,1], bins=nbins)
    channel3_hist = np.histogram(img[:,:,2], bins=nbins)
    # Concatenate the histograms into a single feature vector
    hist_features = np.concatenate((channel1_hist[0], channel2_hist[0], channel3_hist[0]))
    return hist_features
In [6]:
# Define a function to return HOG features and visualization --
def get_hog_features(img, orient=HOG_ORIENTATIONS, pix_per_cell=HOG_PIXELS_PER_CELL,
                     cell_per_block=HOG_CELLS_PER_BLOCK, vis=False, feature_vec=True):      
    denormalized_img = denormalize_pixels(img)
    if vis == True:
        features, hog_image = hog(denormalized_img, orientations=orient, pixels_per_cell=(pix_per_cell, pix_per_cell),
                                  cells_per_block=(cell_per_block, cell_per_block), transform_sqrt=False, 
                                  visualise=vis, feature_vector=feature_vec)
        return features, hog_image
    else:      
        features = hog(denormalized_img, orientations=orient, pixels_per_cell=(pix_per_cell, pix_per_cell),
                       cells_per_block=(cell_per_block, cell_per_block), transform_sqrt=False, 
                       visualise=vis, feature_vector=feature_vec)
        return features
In [7]:
# Define a function to extract features from a list of images
def extract_features(imgs, cspace=COLOR_SPACE, spatial_size=BIN_SPATIAL_SIZE,
                        hist_bins=HIST_NBINS):
    # Create a list to append feature vectors
    features = []
    for file in imgs:
        image = mpimg.imread(file)

        # Image read in from mpimg + .png -> (0 to 1) scaled
        if cspace != 'RGB':
            if cspace == 'HSV':
                feature_image = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
            elif cspace == 'LUV':
                feature_image = cv2.cvtColor(image, cv2.COLOR_RGB2LUV)
            elif cspace == 'HLS':
                feature_image = cv2.cvtColor(image, cv2.COLOR_RGB2HLS)
            elif cspace == 'YUV':
                feature_image = cv2.cvtColor(image, cv2.COLOR_RGB2YUV)
        else: feature_image = np.copy(image)
        
        # Apply bin_spatial() to get spatial color features
        spatial_features = bin_spatial(feature_image, size=spatial_size)
        # Apply color_hist() also with a color space option now
        hist_features = color_hist(feature_image, nbins=hist_bins)
        
        # Call get_hog_features() with vis=False, feature_vec=True
        hog_image = np.copy(image)
        hog_shape = np.asarray(hog_image.shape)
        if HOG_CHANNEL == 'ALL':
            hog_features = []
            for channel in range(len(hog_shape)):
                hog_features.append(get_hog_features(hog_image[:,:,channel]))
            hog_features = np.ravel(hog_features)        
        else:
            hog_features = get_hog_features(hog_image[:,:,HOG_CHANNEL])
        
        # Append the new feature vector to the features list
        features.append(np.concatenate((spatial_features, hist_features, hog_features)))
    # Return list of feature vectors
    return features
In [8]:
## Starting Training Pipeline ##
# Load Image Paths 
images = glob.glob(dataset_path, recursive=True)
cars = []
notcars = []
for image in images:
    if NON_VEHICLES_TOKEN in image:
        notcars.append(image)
    else:
        cars.append(image)
print('Number of Vehicle Images Found:',len(cars),'(images in directory):', dataset_path)
print('Number of Non-Vehicle Images Found:',len(notcars),'(images in directory):', dataset_path)
assert len(images) == len(cars) + len(notcars), 'The subarrays have not split the dataset correctly.'
Number of Vehicle Images Found: 8792 (images in directory): data/training_set/**/*.png
Number of Non-Vehicle Images Found: 8968 (images in directory): data/training_set/**/*.png
In [9]:
# Start Pipeline - Combine and Normalilze Features
car_features = extract_features(cars)
notcar_features = extract_features(notcars)

# Create an array stack of feature vectors
X = np.vstack((car_features, notcar_features)).astype(np.float64)  

# Fit a per-column scaler
X_scaler = StandardScaler().fit(X)

# Apply the scaler to X
scaled_X = X_scaler.transform(X)
car_ind = np.random.randint(0, len(cars))
# Plot an example of raw and scaled features
fig = plt.figure(figsize=(12,4))
plt.subplot(131)
plt.imshow(mpimg.imread(cars[car_ind]))
plt.title('Original Image')
plt.subplot(132)
plt.plot(X[car_ind])
plt.title('Raw Features')
plt.subplot(133)
plt.plot(scaled_X[car_ind])
plt.title('Normalized Features')
fig.tight_layout()

print('Feature Vector size for Cars:', len(car_features[car_ind]))
print('Using Spatial Binning of:',BIN_SPATIAL_SIZE[0],
    'and', HIST_NBINS,'histogram bins')
Feature Vector size for Cars: 8748
Using Spatial Binning of: 32 and 128 histogram bins
In [10]:
# Define the labels vector
y = np.hstack((np.ones(len(car_features)), np.zeros(len(notcar_features))))
In [11]:
# Split up data into randomized training and test sets
rand_state = np.random.randint(0, 100)
X_train, X_test, y_train, y_test = train_test_split(
    scaled_X, y, test_size=VALIDATION_PORTION, random_state=rand_state)
print('Feature vector length:', len(X_train[0]))
Feature vector length: 8748
In [12]:
# Use a linear SVC 
svc = LinearSVC()
# Check the training time for the SVC
t=time.time()
svc.fit(X_train, y_train)
t2 = time.time()
print(round(t2-t, 2), 'Seconds to train SVC...')
# Check the score of the SVC
print('Test Accuracy of SVC = ', round(svc.score(X_test, y_test), 4))
# Check the prediction time for a single sample
t=time.time()
n_predict = N_PREDICTIONS
print('SVC predicts: ', svc.predict(X_test[0:n_predict]))
print('For these',n_predict, 'labels: ', y_test[0:n_predict])
t2 = time.time()
print(round(t2-t, 5), 'Seconds to predict', n_predict,'labels with SVC')
73.04 Seconds to train SVC...
Test Accuracy of SVC =  0.9914
SVC predicts:  [ 1.  0.  1.  0.  1.  1.  0.  0.  1.  0.  0.  1.  0.  1.  0.  0.  1.  0.
  1.  0.  1.  0.  1.  0.  1.  0.  1.  1.  1.  1.  1.  0.  0.  0.  1.  0.
  1.  0.  1.  1.  1.  0.  0.  1.  1.  0.  1.  0.  1.  1.  1.  0.  1.  1.
  1.  1.  0.  1.  0.  0.  1.  0.  1.  0.  0.  1.  1.  1.  0.  1.  1.  1.
  0.  0.  0.  0.  0.  1.  0.  1.  1.  1.  1.  1.  0.  1.  1.  1.  1.  0.
  1.  1.  0.  0.  0.  1.  0.  0.  0.  1.]
For these 100 labels:  [ 1.  0.  1.  0.  1.  1.  0.  0.  1.  0.  0.  1.  0.  1.  0.  0.  1.  0.
  1.  0.  1.  0.  1.  0.  1.  0.  1.  1.  1.  1.  1.  0.  0.  0.  1.  0.
  1.  0.  1.  1.  1.  0.  0.  1.  1.  0.  1.  0.  1.  1.  1.  1.  0.  1.
  1.  1.  0.  1.  0.  0.  1.  0.  1.  0.  0.  1.  1.  1.  0.  1.  1.  1.
  0.  0.  0.  0.  0.  1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  1.  1.  0.
  1.  1.  0.  0.  0.  1.  0.  0.  0.  1.]
0.04033 Seconds to predict 100 labels with SVC
In [13]:
#Save Support Vector Classifier to Datacache
def save_to_datacache(support_vector_classifier, datacache_dir=DATACACHE_DIRECTORY):
    os.makedirs(datacache_dir, exist_ok=True)
    svc_pickle = os.path.join(datacache_dir,"svc_pickle.p")
    if not os.path.exists(svc_pickle): 
        svc_hyperparameters = {'svc': svc,
                               'X_scaler':X_scaler,
                               'SPATIAL': SPATIAL, 
                               'HIST_NBINS': HIST_NBINS,
                               'COLOR_SPACE': COLOR_SPACE,
                               'HOG_ORIENTATIONS': HOG_ORIENTATIONS,
                               'HOG_PIXELS_PER_CELL': HOG_PIXELS_PER_CELL,
                               'HOG_CELLS_PER_BLOCK': HOG_CELLS_PER_BLOCK,
                               'HOG_CHANNEL': HOG_CHANNEL
                              }

        pickle.dump(svc_hyperparameters, open(svc_pickle, "wb"))
    
# Save classifier and parameters to datacache directory  
save_to_datacache(svc)

Finished Training SVC - Now to Utilize Sliding Windows

In [14]:
import matplotlib.image as mpimg
import numpy as np
import cv2
from skimage.feature import hog
In [15]:
# Sliding Window Constants
WORKING_DIRECTORY = 'data/'
DATACACHE_DIRECTORY = os.path.join(WORKING_DIRECTORY, 'datacache/')
svc_pickle = os.path.join(DATACACHE_DIRECTORY,"svc_pickle.p")
TESTING_DATASET_DIRECTORY = 'testing_dataset/'
TESTING_PIPELINE_SETUP_DIR= 'test_images/'

testset_path = "{}{}{}".format(WORKING_DIRECTORY, TESTING_PIPELINE_SETUP_DIR, '*.jpg')


with open(svc_pickle, mode='rb') as f:
    svc_hyperparameters = pickle.load(f)
    
    
## Feature Extraction Parameters ##
# Spatial Binning
SVC = svc_hyperparameters['svc']
X_SCALER = svc_hyperparameters['X_scaler']
SPATIAL = svc_hyperparameters['SPATIAL']

BIN_SPATIAL_SIZE = (SPATIAL, SPATIAL)
# Color Histogram
HIST_NBINS = svc_hyperparameters['HIST_NBINS']
COLOR_SPACE = svc_hyperparameters['COLOR_SPACE']
# HOG Parameters
HOG_ORIENTATIONS = svc_hyperparameters['HOG_ORIENTATIONS']
HOG_PIXELS_PER_CELL = svc_hyperparameters['HOG_PIXELS_PER_CELL']
HOG_CELLS_PER_BLOCK = svc_hyperparameters['HOG_CELLS_PER_BLOCK']
HOG_CHANNEL = svc_hyperparameters['HOG_CHANNEL'] # Can be 0, 1, 2, or "ALL"

BBOX_COLOR = (0, 0, 255)
BBOX_THICK = 6

## Sliding Windows Parameters - Horizon ##
SW_XSTART_STOPS = [(None, None), (None, None), (200, 1000),(400, 1300)]
SW_YSTART_STOPS = [(420, 650), (400, 575), (375, 500), (400,556)]
SW_XY_WINDOWS = [(240, 150), (120,96), (60,48), (96,96)]
SW_XY_OVERLAPS = [(0.75, 0.55), (0.75,0.5), (0.75,0.5), (0.5,0.5)]


SW_SPATIAL_FEAT_FLAG = True
SW_HOG_FEAT_FLAG = True
SW_COLOR_HIST_FEAT_FLAG = True
In [16]:
# Define a function to draw bounding boxes
def draw_boxes(img, bboxes, color=BBOX_COLOR, thick=BBOX_THICK):
    # Make a copy of the image
    imcopy = np.copy(img)
    # Iterate through the bounding boxes
    for bbox in bboxes:
        # Draw a rectangle given bbox coordinates
        cv2.rectangle(imcopy, bbox[0], bbox[1], color, thick)
    return imcopy
In [17]:
# Define a function that takes an image, a list of start_stop positions in both x and y, 
# a list of window sizes (x and y dimensions), and a list of overlap fraction (for both x and y)
def slide_windows(img, x_start_stops=[[None, None]], y_start_stops=[[None, None]],
                 xy_windows=[(64, 64)], xy_overlaps=[(0.5, 0.5)]):

    windows = []
    for i in range(len(x_start_stops)):
        if len(x_start_stops) == len(xy_windows) and len(x_start_stops) == len(xy_overlaps):
            windows = slide_window(img, np.asarray(x_start_stops[i]), np.asarray(y_start_stops[i]),
                                np.asarray(xy_windows[i]), np.asarray(xy_overlaps[i]), windows)
        else:
            windows = slide_window(img, np.asarray(x_start_stops[i]), np.asarray(y_start_stops[i]),
                                np.asarray(xy_windows[0]), np.asarray(xy_overlaps[0]), windows)
            
    return windows
In [18]:
# Define a function that takes an image, start and stop positions in both x and y, 
# window size (x and y dimensions), and overlap fraction (for both x and y)
def slide_window(img, x_start_stop=[None, None], y_start_stop=[None, None], 
                    xy_window=(64, 64), xy_overlap=(0.5, 0.5), window_list=[]):
    # If x and/or y start/stop positions not defined, set to image size
    if x_start_stop[0] == None:
        x_start_stop[0] = 0
#     elif x_start_stop[0] >= img.shape[1]:
#         x_start_stop[0] = img.shape[1] - 64
        
    if x_start_stop[1] == None or x_start_stop[1] >= img.shape[1]:
        x_start_stop[1] = img.shape[1]
       
        
    if y_start_stop[0] == None:
        y_start_stop[0] = 0
#     elif y_start_stop[0] >= img.shape[0]:
#         y_start_stop[0] = img.shape[0] - 64
    if y_start_stop[1] == None or y_start_stop[1] >= img.shape[0]:
        y_start_stop[1] = img.shape[0]


    # Compute the span of the region to be searched    
    xspan = x_start_stop[1] - x_start_stop[0]
    yspan = y_start_stop[1] - y_start_stop[0]
    
    # Compute the number of pixels per step in x/y
    nx_pix_per_step = np.int(xy_window[0]*(1 - xy_overlap[0]))
    ny_pix_per_step = np.int(xy_window[1]*(1 - xy_overlap[1]))
    
    # Compute the number of windows in x/y
    nx_buffer = np.int(xy_window[0]*(xy_overlap[0]))
    ny_buffer = np.int(xy_window[1]*(xy_overlap[1]))
    nx_windows = np.int((xspan-nx_buffer)/nx_pix_per_step) 
    ny_windows = np.int((yspan-ny_buffer)/ny_pix_per_step) 

    # Loop through finding x and y window positions
    for ys in range(ny_windows):
        for xs in range(nx_windows):
            # Calculate window position
            startx = xs*nx_pix_per_step + x_start_stop[0]
            endx = startx + xy_window[0]
            starty = ys*ny_pix_per_step + y_start_stop[0]
            endy = starty + xy_window[1]
            
            # Append window position to list
            window_list.append(((startx, starty), (endx, endy)))
    return window_list
In [19]:
#Define a function for plotting multiple images
def visualize(fig, rows, cols, imgs, titles):
    for i, img in enumerate(imgs):
        plt.subplot(rows, cols, i+1)
        plt.title(i+1)
        img_dims = len(img.shape)
        if img_dims < 3:
            plt.imshow(img, cmap='hot')
            plt.title(titles[i])
        else:
            plt.imshow(img)
            plt.title(titles[i])
In [20]:
# Define a function to extract features from a single image window
# This function is very similar to extract_features()
# just for a single image rather than list of images
def single_img_features(img, color_space=COLOR_SPACE, spatial_size=(32, 32),
                        hist_bins=32, orient=9, 
                        pix_per_cell=8, cell_per_block=2, hog_channel=0,
                        spatial_feat=True, hist_feat=True, hog_feat=True):    
    #1) Define an empty list to receive features
    img_features = []
    #2) Apply color conversion if other than 'RGB'
    if color_space != 'RGB':
        if color_space == 'HSV':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
        elif color_space == 'LUV':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2LUV)
        elif color_space == 'HLS':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2HLS)
        elif color_space == 'YUV':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2YUV)
        elif color_space == 'YCrCb':
            feature_image = cv2.cvtColor(img, cv2.COLOR_RGB2YCrCb)
    else: feature_image = np.copy(img)      
    #3) Compute spatial features if flag is set
    if spatial_feat == True:
        spatial_features = bin_spatial(feature_image, size=spatial_size)
        #4) Append features to list
        img_features.append(spatial_features)
    #5) Compute histogram features if flag is set
    if hist_feat == True:
        hist_features = color_hist(feature_image, nbins=hist_bins)
        #6) Append features to list
        img_features.append(hist_features)
    #7) Compute HOG features if flag is set
    if hog_feat == True:
        if hog_channel == 'ALL':
            hog_features = []
            for channel in range(feature_image.shape[2]):
                hog_features.extend(get_hog_features(feature_image[:,:,channel], 
                                    orient, pix_per_cell, cell_per_block, 
                                    vis=False, feature_vec=True))      
        else:
            hog_features = get_hog_features(feature_image[:,:,hog_channel], orient, 
                        pix_per_cell, cell_per_block, vis=False, feature_vec=True)
        #8) Append features to list
        img_features.append(hog_features)

    #9) Return concatenated array of features
    return np.concatenate(img_features)
In [21]:
# Define a function you will pass an image 
# and the list of windows to be searched (output of slide_windows())
def search_windows(img, windows, svc=SVC, X_scaler=X_SCALER, color_space=COLOR_SPACE, 
                    spatial_size=BIN_SPATIAL_SIZE, hist_bins=HIST_NBINS, 
                    orient=HOG_ORIENTATIONS, pix_per_cell=HOG_PIXELS_PER_CELL, cell_per_block=HOG_CELLS_PER_BLOCK, 
                    hog_channel=HOG_CHANNEL, spatial_feat=SW_SPATIAL_FEAT_FLAG, 
                    hist_feat=SW_COLOR_HIST_FEAT_FLAG, hog_feat=SW_HOG_FEAT_FLAG):
            
    #1) Create an empty list to receive positive detection windows
    on_windows = []
        
    #2) Iterate over all windows in the list
    for window in windows:
        #3) Extract the test window from original image
        if window[0][0] <= 0:
            x_start = 0
        else:
            x_start = window[0][0]
        if window[1][0] >= img.shape[1]:
            x_stop = img.shape[1]
        else:
            x_stop = window[1][0]

        if window[0][1] <= 0:
            y_start = 0
        else:
            y_start = window[0][1]
        if window[1][1] >= img.shape[0]:
            y_stop = img.shape[0]
        else:
            y_stop = window[1][1]
        #print('Window Dims:', window)
        #print('window[0][0]:', window[0][0])
        #print('window[1][0]:',window[1][0])
        #print('img[window[0][1]:window[1][1], window[0][0]:window[1][0]] shape:', img[window[0][1]:window[1][1], window[0][0]:window[1][0]].shape)
        test_img = cv2.resize(img[y_start:y_stop, x_start:x_stop], (DEFAULT_LENGTH, DEFAULT_WIDTH))      
        
        #4) Extract features for that window using single_img_features()
        features = single_img_features(test_img, color_space=color_space, 
                            spatial_size=spatial_size, hist_bins=hist_bins, 
                            orient=orient, pix_per_cell=pix_per_cell, 
                            cell_per_block=cell_per_block, 
                            hog_channel=hog_channel, spatial_feat=spatial_feat, 
                            hist_feat=hist_feat, hog_feat=hog_feat)
        #5) Scale extracted features to be fed to classifier
        test_features = X_scaler.transform(np.array(features).reshape(1, -1))
        #6) Predict using your classifier
        prediction = svc.predict(test_features)
        #7) If positive (prediction == 1) then save the window
        if prediction == 1: # Car detected
            on_windows.append(window)
            heatmap[window[0][1]:window[1][1], window[0][0]:window[1][0]] +=1


    #8) Return windows for positive detections
    return on_windows, heatmap
    
In [22]:
# Try Scaling Windows on Test Images
image_paths = glob.glob(testset_path, recursive=True)
print('Found',len(image_paths),'images in directory:', testset_path)
Found 6 images in directory: data/test_images/*.jpg
In [ ]:
 
In [23]:
from scipy.ndimage.measurements import label

def apply_threshold(heatmap, threshold):
    # Zero out pixels below the threshold
    heatmap[heatmap <= threshold] = 0
    return heatmap

def draw_labeled_bboxes(img, labels):
    # Iterate through all detected cars
    for car_number in range(1, labels[1] + 1):
        #Find pixels with each car_number label value
        nonzero = (labels[0] == car_number).nonzero()
        # Identify x and y values of those pixels
        nonzeroy = np.array(nonzero[0])
        nonzerox = np.array(nonzero[1])
        #Define a bounding box based on min/max x and y
        bbox = ((np.min(nonzerox), np.min(nonzeroy)), (np.max(nonzerox), np.max(nonzeroy)))
        #Draw the box on the image
        cv2.rectangle(img, bbox[0], bbox[1], BBOX_COLOR, BBOX_THICK)
    # Return the image
    return img
In [24]:
# Define a single function that can extract features using hog sub-sampling and make predictions

out_images = []
out_titles = []

## Sliding Windows Parameters ##
SW_XSTART_STOPS = [(None, None), (None, None), (192, 1216),(None, None), (200,None)]#, (400, 1300),(200, 1000),(400, 1300)]
SW_YSTART_STOPS = [(192, 640), (416, 640),(384, 576),(416, 640), (384, 512)]#, (500, 600), (375, 500), (400,656)]
SW_XY_WINDOWS = [(256, 128), (96,96), (128, 96), (96, 64), (64,64)]#, (96,64), (64,48), (96,96)]
SW_XY_OVERLAPS = [(0.75, 0.25),(0.750,0.50), (0.750, 0.350), (0.750, 0.500), (.75,.75)]#, (0.75,0.5), (0.75,0.5), (0.5,0.5)]


for img_path in image_paths:
    t1 = time.time()
    img = mpimg.imread(img_path)
    draw_img = np.copy(img)
    img = normalize_pixels(img).astype(np.float32)
    #Make a heatmap of zeros
    heatmap = np.zeros_like(img[:,:,0])
    windows = []
    hot_windows = []
    threshold = 7
    filename = os.path.split(img_path)[-1]
    
    windows_1 = slide_windows(img, x_start_stops=SW_XSTART_STOPS, y_start_stops=SW_YSTART_STOPS, 
                           xy_windows=SW_XY_WINDOWS, 
                           xy_overlaps=SW_XY_OVERLAPS)

    hot_windows_1, heatmap = search_windows(img, windows_1, SVC, X_SCALER, color_space=COLOR_SPACE,
                                 spatial_size=BIN_SPATIAL_SIZE, hist_bins=HIST_NBINS, orient=HOG_ORIENTATIONS,
                                 pix_per_cell=HOG_PIXELS_PER_CELL, cell_per_block=HOG_CELLS_PER_BLOCK,
                                 hog_channel=HOG_CHANNEL, spatial_feat=SW_SPATIAL_FEAT_FLAG, hog_feat=SW_HOG_FEAT_FLAG,
                                 hist_feat=SW_COLOR_HIST_FEAT_FLAG)

    print('BBoxes Found:', len(hot_windows_1))
    windows.extend(windows_1)
    hot_windows.extend(hot_windows_1)
    
    window_img = draw_boxes(draw_img, hot_windows, color=BBOX_COLOR, thick=BBOX_THICK)
    
    labels = label(apply_threshold(heatmap, threshold))
    # Draw bounding boxes on a copy of the image       
    window_img_thresh = draw_labeled_bboxes(draw_img, labels)
    
    
    out_images.append(window_img_thresh)
    out_titles.append(filename)
    out_images.append(apply_threshold(heatmap, threshold))
    out_titles.append(filename)
    
    print(time.time()-t1, 'seconds to process one image search', len(windows), 'windows')

fig = plt.figure(figsize=(12,24))
visualize(fig, 8, 2, out_images, out_titles)
BBoxes Found: 63
6.139443874359131 seconds to process one image search 896 windows
BBoxes Found: 28
5.854285001754761 seconds to process one image search 896 windows
BBoxes Found: 38
5.796109914779663 seconds to process one image search 896 windows
BBoxes Found: 52
5.980740785598755 seconds to process one image search 896 windows
BBoxes Found: 75
5.633599042892456 seconds to process one image search 896 windows
BBoxes Found: 43
5.626996040344238 seconds to process one image search 896 windows
In [ ]:
 
In [ ]:
 

Explore HOG Sub-Sampling Window Search

We want a more efficient way to detect vehicles. This approach will allow for only a single call to get HOG features. The pipeline will then find a sub sample

In [25]:
SW_CONVERT_COLOR = 'RGB2YCrCb'
def convert_color(img, conv=SW_CONVERT_COLOR):
    if conv == 'RGB2YCrCb':
        return cv2.cvtColor(img, cv2.COLOR_RGB2YCrCb)
    if conv == 'BGR2YCrCb':
        return cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
    if conv == 'RGB2LUV':
        return cv2.cvtColor(img, cv2.COLOR_RGB2LUV)
In [26]:
# Define a single function that can extract features using hog sub-sampling and make predictions
out_images = []
out_maps = []
out_titles = []
out_boxes = []

## Sliding Window Parameters - HOG Sub-Sampling ##
SW_YSTART = 400
SW_YSTOP = 665
SW_SCALE = 1.75

ystart = SW_YSTART
ystop = SW_YSTOP
scale = SW_SCALE
spatial_size=BIN_SPATIAL_SIZE
hist_bins=HIST_NBINS
orient=HOG_ORIENTATIONS
pix_per_cell=HOG_PIXELS_PER_CELL
cell_per_block=HOG_CELLS_PER_BLOCK
hog_channel=HOG_CHANNEL
spatial_feat=SW_SPATIAL_FEAT_FLAG
hog_feat=SW_HOG_FEAT_FLAG
hist_feat=SW_COLOR_HIST_FEAT_FLAG


#Iterate over the test images
for img_path in image_paths:
    img_boxes = []
    t1 = time.time()
    count = 0
    img = mpimg.imread(img_path)
    draw_img = np.copy(img)
    
    #Make a heatmap of zeros
    heatmap = np.zeros_like(img[:,:,0])
    img = normalize_pixels(img).astype(np.float32)
    img_to_search = img[ystart:ystop,:,:]
    ctrans_tosearch = convert_color(img_to_search, conv=SW_CONVERT_COLOR)
    if scale != 1:
        imshape = ctrans_tosearch.shape
        ctrans_tosearch = cv2.resize(ctrans_tosearch, (np.int(imshape[1]/scale), np.int(imshape[0]/scale)))

    ch1 = ctrans_tosearch[:,:,0]
    ch2 = ctrans_tosearch[:,:,1]
    ch3 = ctrans_tosearch[:,:,2]
    
    # Define blocks and steps as above
    nxblocks = (ch1.shape[1] // pix_per_cell)-1
    nyblocks = (ch1.shape[0] // pix_per_cell)-1 
    nfeat_per_block = orient*cell_per_block**2
    window = HOG_PIXELS_PER_CELL*HOG_PIXELS_PER_CELL # 8 cells and 8 pix per cell
    nblocks_per_window = (window // pix_per_cell)-1  # The // division is used for integers (for indices)
    cells_per_step = 2  # Instead of overlap, define how many cells to step
    nxsteps = (nxblocks - nblocks_per_window) // cells_per_step # The // division is used for integers (for indices)
    nysteps = (nyblocks - nblocks_per_window) // cells_per_step # The // division is used for integers (for indices)
    
    # Compute individual channel HOG features for the entire image
    hog1 = get_hog_features(ch1, orient, pix_per_cell, cell_per_block, feature_vec=False)
    hog2 = get_hog_features(ch2, orient, pix_per_cell, cell_per_block, feature_vec=False)
    hog3 = get_hog_features(ch3, orient, pix_per_cell, cell_per_block, feature_vec=False)


    for xb in range(nxsteps):
        for yb in range(nysteps):
            count += 1
            ypos = yb*cells_per_step
            xpos = xb*cells_per_step

            # Extract HOG for this particular patch
            hog_feat1 = hog1[ypos:ypos+nblocks_per_window, xpos:xpos+nblocks_per_window].ravel() 
            hog_feat2 = hog2[ypos:ypos+nblocks_per_window, xpos:xpos+nblocks_per_window].ravel() 
            hog_feat3 = hog3[ypos:ypos+nblocks_per_window, xpos:xpos+nblocks_per_window].ravel() 
            hog_features = np.hstack((hog_feat1, hog_feat2, hog_feat3))
            
            xleft = xpos*pix_per_cell
            ytop = ypos*pix_per_cell
            
            # Extract the image patch
            subimg = cv2.resize(ctrans_tosearch[ytop:ytop+window, xleft:xleft+window], (DEFAULT_LENGTH, DEFAULT_WIDTH))

            # Get color features
            spatial_features = bin_spatial(subimg, size=BIN_SPATIAL_SIZE)
            hist_features = color_hist(subimg, nbins=HIST_NBINS)
            
            
            test_feats = np.hstack((spatial_features, hist_features, hog_features))
            # Scale features and make a prediction
            test_features = X_SCALER.transform(test_feats.reshape(1, -1))
            test_prediction = SVC.predict(test_features)

            if test_prediction == 1:
                xbox_left = np.int(xleft*scale)
                ytop_draw = np.int(ytop*scale)
                win_draw = np.int(window*scale)
                cv2.rectangle(draw_img,(xbox_left, ytop_draw+ystart),
                              (xbox_left+win_draw, ytop_draw+win_draw+ystart),BBOX_COLOR,6)
                img_boxes.append(((xbox_left, ytop_draw+ystart),
                              (xbox_left+win_draw,ytop_draw+win_draw+ystart)))

                heatmap[ytop_draw+ystart:ytop_draw+win_draw+ystart, xbox_left:xbox_left+win_draw] +=1
        print(time.time()-t1, 'seconds to run, total windows = ', count)

    out_images.append(draw_img)

    out_titles.append(os.path.split(img_path)[-1])
    out_titles.append(os.path.split(img_path)[-1])
    out_images.append(heatmap)
    out_maps.append(heatmap)
    out_boxes.append(img_boxes)
    
fig = plt.figure(figsize=(12,24))
visualize(fig, 8, 2, out_images, out_titles)
0.5049028396606445 seconds to run, total windows =  5
0.5097768306732178 seconds to run, total windows =  10
0.5156018733978271 seconds to run, total windows =  15
0.520331859588623 seconds to run, total windows =  20
0.524561882019043 seconds to run, total windows =  25
0.5290658473968506 seconds to run, total windows =  30
0.5364840030670166 seconds to run, total windows =  35
0.5428338050842285 seconds to run, total windows =  40
0.5487217903137207 seconds to run, total windows =  45
0.5542738437652588 seconds to run, total windows =  50
0.5586779117584229 seconds to run, total windows =  55
0.5642008781433105 seconds to run, total windows =  60
0.5701339244842529 seconds to run, total windows =  65
0.5747618675231934 seconds to run, total windows =  70
0.5796678066253662 seconds to run, total windows =  75
0.5856189727783203 seconds to run, total windows =  80
0.5902268886566162 seconds to run, total windows =  85
0.5951178073883057 seconds to run, total windows =  90
0.600916862487793 seconds to run, total windows =  95
0.6053287982940674 seconds to run, total windows =  100
0.6094529628753662 seconds to run, total windows =  105
0.614710807800293 seconds to run, total windows =  110
0.6199808120727539 seconds to run, total windows =  115
0.624439001083374 seconds to run, total windows =  120
0.630335807800293 seconds to run, total windows =  125
0.6351428031921387 seconds to run, total windows =  130
0.6401867866516113 seconds to run, total windows =  135
0.6446669101715088 seconds to run, total windows =  140
0.6514937877655029 seconds to run, total windows =  145
0.6570358276367188 seconds to run, total windows =  150
0.663597822189331 seconds to run, total windows =  155
0.6686148643493652 seconds to run, total windows =  160
0.6736209392547607 seconds to run, total windows =  165
0.6780269145965576 seconds to run, total windows =  170
0.684074878692627 seconds to run, total windows =  175
0.6887547969818115 seconds to run, total windows =  180
0.6935648918151855 seconds to run, total windows =  185
0.6993618011474609 seconds to run, total windows =  190
0.7039749622344971 seconds to run, total windows =  195
0.7089459896087646 seconds to run, total windows =  200
0.715425968170166 seconds to run, total windows =  205
0.27463388442993164 seconds to run, total windows =  5
0.3027670383453369 seconds to run, total windows =  10
0.30953502655029297 seconds to run, total windows =  15
0.3167860507965088 seconds to run, total windows =  20
0.3211100101470947 seconds to run, total windows =  25
0.32819390296936035 seconds to run, total windows =  30
0.34590792655944824 seconds to run, total windows =  35
0.3529999256134033 seconds to run, total windows =  40
0.3584778308868408 seconds to run, total windows =  45
0.363217830657959 seconds to run, total windows =  50
0.3691060543060303 seconds to run, total windows =  55
0.37427592277526855 seconds to run, total windows =  60
0.3787999153137207 seconds to run, total windows =  65
0.3849630355834961 seconds to run, total windows =  70
0.3895699977874756 seconds to run, total windows =  75
0.39406490325927734 seconds to run, total windows =  80
0.3998880386352539 seconds to run, total windows =  85
0.40448999404907227 seconds to run, total windows =  90
0.4091379642486572 seconds to run, total windows =  95
0.41369104385375977 seconds to run, total windows =  100
0.4196929931640625 seconds to run, total windows =  105
0.4245610237121582 seconds to run, total windows =  110
0.4322328567504883 seconds to run, total windows =  115
0.43798398971557617 seconds to run, total windows =  120
0.44490504264831543 seconds to run, total windows =  125
0.45354485511779785 seconds to run, total windows =  130
0.45980286598205566 seconds to run, total windows =  135
0.46790289878845215 seconds to run, total windows =  140
0.47234582901000977 seconds to run, total windows =  145
0.47877001762390137 seconds to run, total windows =  150
0.4859769344329834 seconds to run, total windows =  155
0.4907710552215576 seconds to run, total windows =  160
0.4959568977355957 seconds to run, total windows =  165
0.5029919147491455 seconds to run, total windows =  170
0.5080618858337402 seconds to run, total windows =  175
0.512563943862915 seconds to run, total windows =  180
0.5196018218994141 seconds to run, total windows =  185
0.5246620178222656 seconds to run, total windows =  190
0.5318288803100586 seconds to run, total windows =  195
0.5458660125732422 seconds to run, total windows =  200
0.5751869678497314 seconds to run, total windows =  205
0.2413930892944336 seconds to run, total windows =  5
0.24631905555725098 seconds to run, total windows =  10
0.2507901191711426 seconds to run, total windows =  15
0.2568230628967285 seconds to run, total windows =  20
0.2614939212799072 seconds to run, total windows =  25
0.26643991470336914 seconds to run, total windows =  30
0.2709369659423828 seconds to run, total windows =  35
0.27755308151245117 seconds to run, total windows =  40
0.28243494033813477 seconds to run, total windows =  45
0.2873079776763916 seconds to run, total windows =  50
0.29311704635620117 seconds to run, total windows =  55
0.29760098457336426 seconds to run, total windows =  60
0.301969051361084 seconds to run, total windows =  65
0.3076610565185547 seconds to run, total windows =  70
0.3128371238708496 seconds to run, total windows =  75
0.3172719478607178 seconds to run, total windows =  80
0.321491003036499 seconds to run, total windows =  85
0.3280909061431885 seconds to run, total windows =  90
0.332672119140625 seconds to run, total windows =  95
0.3372180461883545 seconds to run, total windows =  100
0.343189001083374 seconds to run, total windows =  105
0.34780192375183105 seconds to run, total windows =  110
0.35210394859313965 seconds to run, total windows =  115
0.35776400566101074 seconds to run, total windows =  120
0.36263394355773926 seconds to run, total windows =  125
0.36702799797058105 seconds to run, total windows =  130
0.3719189167022705 seconds to run, total windows =  135
0.37848591804504395 seconds to run, total windows =  140
0.38363003730773926 seconds to run, total windows =  145
0.38829994201660156 seconds to run, total windows =  150
0.3933241367340088 seconds to run, total windows =  155
0.39841794967651367 seconds to run, total windows =  160
0.4029700756072998 seconds to run, total windows =  165
0.40776896476745605 seconds to run, total windows =  170
0.4121110439300537 seconds to run, total windows =  175
0.41727709770202637 seconds to run, total windows =  180
0.4219949245452881 seconds to run, total windows =  185
0.4269111156463623 seconds to run, total windows =  190
0.43256211280822754 seconds to run, total windows =  195
0.436877965927124 seconds to run, total windows =  200
0.4418361186981201 seconds to run, total windows =  205
0.25562500953674316 seconds to run, total windows =  5
0.26041102409362793 seconds to run, total windows =  10
0.26497387886047363 seconds to run, total windows =  15
0.2693660259246826 seconds to run, total windows =  20
0.27472805976867676 seconds to run, total windows =  25
0.27913808822631836 seconds to run, total windows =  30
0.28467488288879395 seconds to run, total windows =  35
0.2901759147644043 seconds to run, total windows =  40
0.294666051864624 seconds to run, total windows =  45
0.2995290756225586 seconds to run, total windows =  50
0.3043079376220703 seconds to run, total windows =  55
0.3095400333404541 seconds to run, total windows =  60
0.3144259452819824 seconds to run, total windows =  65
0.3186819553375244 seconds to run, total windows =  70
0.3238558769226074 seconds to run, total windows =  75
0.3285698890686035 seconds to run, total windows =  80
0.334183931350708 seconds to run, total windows =  85
0.34037208557128906 seconds to run, total windows =  90
0.34554386138916016 seconds to run, total windows =  95
0.3512899875640869 seconds to run, total windows =  100
0.356752872467041 seconds to run, total windows =  105
0.36129188537597656 seconds to run, total windows =  110
0.3658590316772461 seconds to run, total windows =  115
0.3710639476776123 seconds to run, total windows =  120
0.37671494483947754 seconds to run, total windows =  125
0.38095688819885254 seconds to run, total windows =  130
0.38611793518066406 seconds to run, total windows =  135
0.39148592948913574 seconds to run, total windows =  140
0.3960549831390381 seconds to run, total windows =  145
0.40100598335266113 seconds to run, total windows =  150
0.4065260887145996 seconds to run, total windows =  155
0.4110748767852783 seconds to run, total windows =  160
0.4158589839935303 seconds to run, total windows =  165
0.4206099510192871 seconds to run, total windows =  170
0.42597389221191406 seconds to run, total windows =  175
0.43041300773620605 seconds to run, total windows =  180
0.43573999404907227 seconds to run, total windows =  185
0.441727876663208 seconds to run, total windows =  190
0.4468519687652588 seconds to run, total windows =  195
0.45227599143981934 seconds to run, total windows =  200
0.45786595344543457 seconds to run, total windows =  205
0.1985149383544922 seconds to run, total windows =  5
0.20326900482177734 seconds to run, total windows =  10
0.20781493186950684 seconds to run, total windows =  15
0.21226787567138672 seconds to run, total windows =  20
0.2174079418182373 seconds to run, total windows =  25
0.2218019962310791 seconds to run, total windows =  30
0.22667288780212402 seconds to run, total windows =  35
0.23107290267944336 seconds to run, total windows =  40
0.23610901832580566 seconds to run, total windows =  45
0.24107789993286133 seconds to run, total windows =  50
0.2455458641052246 seconds to run, total windows =  55
0.25117993354797363 seconds to run, total windows =  60
0.2554819583892822 seconds to run, total windows =  65
0.2601809501647949 seconds to run, total windows =  70
0.26589488983154297 seconds to run, total windows =  75
0.2700619697570801 seconds to run, total windows =  80
0.27513694763183594 seconds to run, total windows =  85
0.28063488006591797 seconds to run, total windows =  90
0.28575801849365234 seconds to run, total windows =  95
0.2907140254974365 seconds to run, total windows =  100
0.2957730293273926 seconds to run, total windows =  105
0.30121898651123047 seconds to run, total windows =  110
0.30605602264404297 seconds to run, total windows =  115
0.31082892417907715 seconds to run, total windows =  120
0.3163590431213379 seconds to run, total windows =  125
0.3208298683166504 seconds to run, total windows =  130
0.3260798454284668 seconds to run, total windows =  135
0.3311760425567627 seconds to run, total windows =  140
0.3357269763946533 seconds to run, total windows =  145
0.3404428958892822 seconds to run, total windows =  150
0.3450319766998291 seconds to run, total windows =  155
0.3506429195404053 seconds to run, total windows =  160
0.35521697998046875 seconds to run, total windows =  165
0.35997700691223145 seconds to run, total windows =  170
0.36499500274658203 seconds to run, total windows =  175
0.37018585205078125 seconds to run, total windows =  180
0.37491583824157715 seconds to run, total windows =  185
0.3794078826904297 seconds to run, total windows =  190
0.3846008777618408 seconds to run, total windows =  195
0.38925600051879883 seconds to run, total windows =  200
0.3947429656982422 seconds to run, total windows =  205
0.1954050064086914 seconds to run, total windows =  5
0.2001960277557373 seconds to run, total windows =  10
0.20557403564453125 seconds to run, total windows =  15
0.2102818489074707 seconds to run, total windows =  20
0.21645402908325195 seconds to run, total windows =  25
0.22299885749816895 seconds to run, total windows =  30
0.2272939682006836 seconds to run, total windows =  35
0.2325000762939453 seconds to run, total windows =  40
0.23749589920043945 seconds to run, total windows =  45
0.2423548698425293 seconds to run, total windows =  50
0.24811291694641113 seconds to run, total windows =  55
0.25345587730407715 seconds to run, total windows =  60
0.25809502601623535 seconds to run, total windows =  65
0.26297903060913086 seconds to run, total windows =  70
0.2676820755004883 seconds to run, total windows =  75
0.27341198921203613 seconds to run, total windows =  80
0.2783799171447754 seconds to run, total windows =  85
0.2830240726470947 seconds to run, total windows =  90
0.2882249355316162 seconds to run, total windows =  95
0.29323387145996094 seconds to run, total windows =  100
0.29825806617736816 seconds to run, total windows =  105
0.30267786979675293 seconds to run, total windows =  110
0.3078479766845703 seconds to run, total windows =  115
0.31226396560668945 seconds to run, total windows =  120
0.31723499298095703 seconds to run, total windows =  125
0.32256293296813965 seconds to run, total windows =  130
0.327272891998291 seconds to run, total windows =  135
0.33281803131103516 seconds to run, total windows =  140
0.3381359577178955 seconds to run, total windows =  145
0.3425168991088867 seconds to run, total windows =  150
0.34731292724609375 seconds to run, total windows =  155
0.3518259525299072 seconds to run, total windows =  160
0.3569629192352295 seconds to run, total windows =  165
0.3614509105682373 seconds to run, total windows =  170
0.3658740520477295 seconds to run, total windows =  175
0.37090396881103516 seconds to run, total windows =  180
0.37517595291137695 seconds to run, total windows =  185
0.3802909851074219 seconds to run, total windows =  190
0.38486599922180176 seconds to run, total windows =  195
0.3898649215698242 seconds to run, total windows =  200
0.3944690227508545 seconds to run, total windows =  205
In [27]:
# Define a single function that can extract features using hog sub-sampling and make predictions
def find_cars(img, ystart=SW_YSTART, ystop=SW_YSTOP, scale=SW_SCALE, svc=SVC, X_scaler=X_SCALER,
              orient=HOG_ORIENTATIONS, pix_per_cell=HOG_PIXELS_PER_CELL, cell_per_block=HOG_CELLS_PER_BLOCK,
              spatial_size=BIN_SPATIAL_SIZE, hist_bins=HIST_NBINS):

    spatial_feat=SW_SPATIAL_FEAT_FLAG
    hog_feat=SW_HOG_FEAT_FLAG
    hist_feat=SW_COLOR_HIST_FEAT_FLAG
    
    # If y start/stop positions not defined, set to image size      
    if ystart == None or ystart < 0:
        ystart = 0
    if ystop == None or ystop > img.shape[0]:
        ystop = img.shape[0]

    draw_img = np.copy(img)

    #Make a heatmap of zeros
    heatmap = np.zeros_like(img[:,:,0])
    img = normalize_pixels(img).astype(np.float32)
    img_to_search = img[ystart:ystop,:,:]
    ctrans_tosearch = convert_color(img_to_search, conv=SW_CONVERT_COLOR)
    if scale != 1:
        imshape = ctrans_tosearch.shape
        ctrans_tosearch = cv2.resize(ctrans_tosearch, (np.int(imshape[1]/scale), np.int(imshape[0]/scale)))

    ch1 = ctrans_tosearch[:,:,0]
    ch2 = ctrans_tosearch[:,:,1]
    ch3 = ctrans_tosearch[:,:,2]

    # Define blocks and steps as above
    nxblocks = (ch1.shape[1] // pix_per_cell)-1
    nyblocks = (ch1.shape[0] // pix_per_cell)-1 
    nfeat_per_block = orient*cell_per_block**2
    window = HOG_PIXELS_PER_CELL*HOG_PIXELS_PER_CELL # 8 cells and 8 pix per cell
    nblocks_per_window = (window // pix_per_cell)-1  # The // division is used for integers (for indices)
    cells_per_step = 1  # Instead of overlap, define how many cells to step
    nxsteps = (nxblocks - nblocks_per_window) // cells_per_step # The // division is used for integers (for indices)
    nysteps = (nyblocks - nblocks_per_window) // cells_per_step # The // division is used for integers (for indices)

    # Compute individual channel HOG features for the entire image
    hog1 = get_hog_features(ch1, orient, pix_per_cell, cell_per_block, feature_vec=False)
    hog2 = get_hog_features(ch2, orient, pix_per_cell, cell_per_block, feature_vec=False)
    hog3 = get_hog_features(ch3, orient, pix_per_cell, cell_per_block, feature_vec=False)


    for xb in range(nxsteps):
        for yb in range(nysteps):
            ypos = yb*cells_per_step
            xpos = xb*cells_per_step

            # Extract HOG for this particular patch
            hog_feat1 = hog1[ypos:ypos+nblocks_per_window, xpos:xpos+nblocks_per_window].ravel() 
            hog_feat2 = hog2[ypos:ypos+nblocks_per_window, xpos:xpos+nblocks_per_window].ravel() 
            hog_feat3 = hog3[ypos:ypos+nblocks_per_window, xpos:xpos+nblocks_per_window].ravel() 
            hog_features = np.hstack((hog_feat1, hog_feat2, hog_feat3))

            xleft = xpos*pix_per_cell
            ytop = ypos*pix_per_cell

            # Extract the image patch
            subimg = cv2.resize(ctrans_tosearch[ytop:ytop+window, xleft:xleft+window], (DEFAULT_LENGTH, DEFAULT_WIDTH))

            # Get color features
            spatial_features = bin_spatial(subimg, size=BIN_SPATIAL_SIZE)
            hist_features = color_hist(subimg, nbins=HIST_NBINS)

            test_feats = np.hstack((spatial_features, hist_features, hog_features))
            # Scale features and make a prediction
            test_features = X_scaler.transform(test_feats.reshape(1, -1))
            test_prediction = svc.predict(test_features)

            if test_prediction == 1:
                xbox_left = np.int(xleft*scale)
                ytop_draw = np.int(ytop*scale)
                win_draw = np.int(window*scale)
                cv2.rectangle(draw_img,(xbox_left, ytop_draw+ystart),
                              (xbox_left+win_draw, ytop_draw+win_draw+ystart),BBOX_COLOR,6)
                heatmap[ytop_draw+ystart:ytop_draw+win_draw+ystart, xbox_left:xbox_left+win_draw] +=1
    return draw_img, heatmap
In [28]:
# DEFINE A CLASS TO RECEIVE THE CHARACTERISTICS OF EACH VEHICLE DETECTION
# Objects defined as "Vehicles" will be where multiple overlaping detections exists in the heatmap
class Vehicle():
    def __init__(self, bbox):
        self.prev_detected = True # Flag sets if the Vehicle was detected in the last iteration
        self.n_detections = 1 # number of times this vehicle has been detected
        self.n_non_detections = 0 # number of consecutive times this vehicle has not been detected
        self.xpixels = np.arange(bbox[0][0], bbox[1][0]+1) # Pixel x values of last detection
        self.ypixels = np.arange(bbox[0][1], bbox[1][1]+1) # Pixel y values of last detection
        self.recent_xfitted = []
        self.recent_xfitted.append(bbox[0][0]) # x position of the last n fits of the bounding box
        self.bestx = bbox[0][0] # X position of the current fit
        self.recent_yfitted = []
        self.recent_yfitted.append(bbox[0][1]) # Y position of the last n fits of the bounding box
        self.besty = bbox[0][1] # Average y position of the current fit
        self.recent_wfitted = []
        self.recent_wfitted.append(bbox[1][0])
        self.bestw = bbox[1][0] # Average width of the last n fits
        self.recent_hfitted = []
        self.recent_hfitted.append(bbox[1][1]) # Height of the last n fits of the bounding box
        self.besth = bbox[1][1] # Average height of the last n fits
        self.bounding_box = bbox
In [29]:
from scipy.ndimage.measurements import label

def apply_threshold(heatmap, threshold):
    # Zero out pixels below the threshold
    heatmap[heatmap <= threshold] = 0
    return heatmap

def draw_labeled_bboxes(img, labels, smoothing_factor=0, remove_threshold = 10):
    # Iterate through all detected cars
    for car_number in range(1, labels[1] + 1):
        #Find pixels with each car_number label value
        nonzero = (labels[0] == car_number).nonzero()
        # Identify x and y values of those pixels
        nonzeroy = np.array(nonzero[0])
        nonzerox = np.array(nonzero[1])
        # Define a bounding box based on min/max x and y
        bbox = ((np.min(nonzerox), np.min(nonzeroy)), (np.max(nonzerox), np.max(nonzeroy)))

        # Check if bounding box appears in carslist
        found_match = False
        for car in carslist:
            # Check if car's previous pix values are 'close enough' to current bounding_box. If so, grab vehicle
            if(bbox[0][0] in car.recent_xfitted and bbox[0][1] in car.recent_yfitted and 
               bbox[1][0] in car.recent_wfitted and bbox[1][1] in car.recent_hfitted):
                found_match = True
                print('Found a match. Car Number', car_number, '| length nonzerox:',len(nonzerox), '| length nonzeroy:',len(nonzeroy))
                print('Bounding box:',bbox)

                car.n_detections += 1                
                car.prev_detected = True
                car.n_non_detections = 0 # Let's try setting this to 0 initially
                car.xpixels = nonzerox # Pixel x values of current detection
                car.ypixels = nonzeroy # Pixel y values of current detection
                if len(car.recent_xfitted) >= smoothing_factor:
                    car.recent_xfitted.append(bbox[0][0])
                    car.bestx = int(np.mean(car.recent_xfitted[:-smoothing_factor])) # Average x position of the last n fits
                    car.recent_yfitted.append(bbox[0][1]) # Y position of the last n fits of the bounding box
                    car.besty = int(np.mean(car.recent_yfitted[:-smoothing_factor])) # Average y position of the current fit
                    car.recent_wfitted.append(bbox[1][0])
                    car.bestw = int(np.mean(car.recent_wfitted[:-smoothing_factor])) # Average width of the last n fits
                    car.recent_hfitted.append(bbox[1][1]) # Height of the last n fits of the bounding box
                    car.besth = int(np.mean(car.recent_hfitted[:-smoothing_factor])) # Average height of the last n fits
                else:
                    car.recent_xfitted.append(bbox[0][0])
                    car.bestx = int(np.mean(car.recent_xfitted)) # Average x position of the last n fits
                    car.recent_yfitted.append(bbox[0][1]) # Y position of the last n fits of the bounding box
                    car.besty = int(np.mean(car.recent_yfitted)) # Average y position of the current fit
                    car.recent_wfitted.append(bbox[1][0])
                    car.bestw = int(np.mean(car.recent_wfitted)) # Average width of the last n fits
                    car.recent_hfitted.append(bbox[1][1]) # Height of the last n fits of the bounding box
                    car.besth = int(np.mean(car.recent_hfitted)) # Average height of the last n fits
                
                car.bounding_box = ((car.bestx, car.besty),
                                        (car.bestw, car.besth))
                break
        if found_match == False:
            # Add New Vehicle
            car = Vehicle(bbox)
            car.xpixels = nonzerox
            car.ypixels = nonzeroy
            
        #Draw the box on the image
        if (car.n_detections > smoothing_factor and car.n_non_detections == 0):
            cv2.rectangle(img, (car.bestx, car.besty),(car.bestw, car.besth), BBOX_COLOR, BBOX_THICK)
    
        # Add car to carslist
        carslist.append(car)
        
    # Set n_non_detections for each car in carslist that wasn't prev_detected
    # n_non_detections = Number of consecutive times this car has not been detected
    undetected_cars = (car for car in carslist if car.prev_detected is False and car.n_non_detections > 1)
    for car in undetected_cars:
        car.n_non_detections +=1
        if car.n_non_detections > remove_threshold:
            print('Removing Car: ', car.bounding_box)
            carslist.remove(car)
        
    # Return the image
    return img
In [30]:
out_images = []
out_maps = []
out_titles = []
out_boxes = []
carslist = []

## Sliding Window Parameters - HOG Sub-Sampling ##
SW_CONVERT_COLOR = 'RGB2YCrCb'
SW_YSTART = None
SW_YSTOP = None
SW_SCALE = 1.75
BIN_SPATIAL_SIZE = (32,32)
HIST_NBINS = 128
HOG_ORIENTATIONS = 9
HOG_PIXELS_PER_CELL = 8
HOG_CELLS_PER_BLOCK = 2
HOG_CHANNEL = 'ALL' # Can be 0, 1, 2, or "ALL"
SW_SPATIAL_FEAT_FLAG = True
SW_HOG_FEAT_FLAG = True
SW_COLOR_HIST_FEAT_FLAG = True

#Iterate over the test images
for img_path in image_paths:
    img = mpimg.imread(img_path)
    out_img, heatmap = find_cars(img, ystart=SW_YSTART, ystop=SW_YSTOP, scale=SW_SCALE, svc=SVC, X_scaler=X_SCALER,
              orient=HOG_ORIENTATIONS, pix_per_cell=HOG_PIXELS_PER_CELL, cell_per_block=HOG_CELLS_PER_BLOCK,
              spatial_size=BIN_SPATIAL_SIZE, hist_bins=HIST_NBINS)
    labels = label(apply_threshold(heatmap, 2))
    # Draw bounding boxes on a copy of the image       
    draw_img = draw_labeled_bboxes(np.copy(out_img), labels)
    out_images.append(draw_img)
    out_images.append(heatmap)
#     filename = os.path.split(img_path)[-1]
    out_titles.append(filename)
    out_titles.append(filename)

fig = plt.figure(figsize=(12,24))
visualize(fig, 8, 2, out_images, out_titles)
In [61]:
def process_image(img):
    ## Search for cars from previous frame Gather previous bboxes from carslist
    offset = 32
    heatmap_1 = np.zeros_like(img[:,:,0])
    out_img = img
    if len(carslist) > 1:
        bboxes = []
        for car in carslist:
            bboxes.append(((car.bestx, car.besty),(car.bestx+car.bestw, car.besty+car.besth)))
        bboxes = np.array(bboxes)
#         print('Found bboxes of size:', len(bboxes))
#         print('bboxes[:,0]:', bboxes[:,0])
        # Try sliding windows to capture wider bbox
#         windows_1 = slide_windows(img, x_start_stops=bboxes[:,0], y_start_stops=bboxes[:,1], 
#                                 xy_windows=[(32,32)], 
#                                 xy_overlaps=[(0.85, 0.85)])

#         _, heatmap_1 = search_windows(img, windows_1,svc=SVC, X_scaler=X_SCALER, color_space=COLOR_SPACE, 
#                     spatial_size=BIN_SPATIAL_SIZE, hist_bins=HIST_NBINS, 
#                     orient=HOG_ORIENTATIONS, pix_per_cell=HOG_PIXELS_PER_CELL, cell_per_block=HOG_CELLS_PER_BLOCK, 
#                     hog_channel=HOG_CHANNEL, spatial_feat=SW_SPATIAL_FEAT_FLAG, 
#                     hist_feat=SW_COLOR_HIST_FEAT_FLAG, hog_feat=SW_HOG_FEAT_FLAG)

#         labels = label(apply_threshold(heatmap_1, 3))
# #       # Draw bounding boxes on a copy of the image       
#         out_img = draw_labeled_bboxes(np.copy(img), labels, smoothing_factor=2)
    
    ## Search for cars using HOG subsampling (in current frame)
    _, heatmap_2 = find_cars(img, ystart=SW_YSTART, ystop=SW_YSTOP, scale=SW_SCALE, svc=SVC, X_scaler=X_SCALER,
              orient=HOG_ORIENTATIONS, pix_per_cell=HOG_PIXELS_PER_CELL, cell_per_block=HOG_CELLS_PER_BLOCK,
              spatial_size=BIN_SPATIAL_SIZE, hist_bins=HIST_NBINS)
    heatmap = np.add(heatmap_1, heatmap_2)
    #print(heatmap)
    labels = label(apply_threshold(heatmap_2, 3)) 
    draw_img = draw_labeled_bboxes(np.copy(out_img), labels, smoothing_factor=2)
    return draw_img
In [62]:
# carslist = []
# out_img = process_image(mpimg.imread(image_paths[0])) # For Debugging # 
# plt.imshow(out_img)
In [ ]:
#Import packages to edit/save/watch video clips
from moviepy.editor import VideoFileClip
from IPython.display import HTML

SW_YSTART = None #384
SW_YSTOP = None #640
SW_SCALE = 1.75

test_ouput = 'test_output.mp4'
VIDEO_OUTPUT_PATH = os.path.join(WORKING_DIRECTORY, test_ouput)

TEST_VIDEO = 'test_video.mp4'
PROJECT_VIDEO = 'project_video.mp4'
VIDEO_FILE_PATH = os.path.join(WORKING_DIRECTORY, TEST_VIDEO)
clip = VideoFileClip(VIDEO_FILE_PATH)
carslist = []
test_clip = clip.fl_image(process_image)
#%time
test_clip.write_videofile(VIDEO_OUTPUT_PATH, audio=False)

HTML("""
<video width="960" height="540" controls>
 <source src="{0}">
</video>
""".format(VIDEO_OUTPUT_PATH))
[MoviePy] >>>> Building video data/test_output.mp4
[MoviePy] Writing video data/test_output.mp4




  0%|          | 0/39 [00:00<?, ?it/s]




  3%|▎         | 1/39 [00:03<02:21,  3.73s/it]
Found a match. Car Number 1 | length nonzerox: 10976 | length nonzeroy: 10976
Bounding box: ((1064, 364), (1175, 475))
Found a match. Car Number 2 | length nonzerox: 20188 | length nonzeroy: 20188
Bounding box: ((812, 378), (951, 531))
Found a match. Car Number 3 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((196, 588), (293, 685))




  5%|▌         | 2/39 [00:07<02:23,  3.87s/it]
Found a match. Car Number 2 | length nonzerox: 19992 | length nonzeroy: 19992
Bounding box: ((812, 378), (951, 531))




  8%|▊         | 3/39 [00:11<02:17,  3.82s/it]
Found a match. Car Number 1 | length nonzerox: 20188 | length nonzeroy: 20188
Bounding box: ((812, 378), (951, 531))




 10%|█         | 4/39 [00:15<02:11,  3.77s/it]




 13%|█▎        | 5/39 [00:18<02:07,  3.74s/it]




 15%|█▌        | 6/39 [00:22<02:02,  3.70s/it]
Found a match. Car Number 1 | length nonzerox: 19992 | length nonzeroy: 19992
Bounding box: ((812, 378), (951, 531))




 18%|█▊        | 7/39 [00:26<01:57,  3.68s/it]
Found a match. Car Number 1 | length nonzerox: 18424 | length nonzeroy: 18424
Bounding box: ((812, 378), (951, 531))




 21%|██        | 8/39 [00:29<01:53,  3.66s/it]




 23%|██▎       | 9/39 [00:33<01:49,  3.64s/it]
Found a match. Car Number 1 | length nonzerox: 18228 | length nonzeroy: 18228
Bounding box: ((826, 378), (951, 531))




 26%|██▌       | 10/39 [00:37<01:46,  3.66s/it]
Found a match. Car Number 1 | length nonzerox: 19208 | length nonzeroy: 19208
Bounding box: ((812, 378), (951, 531))




 28%|██▊       | 11/39 [00:40<01:42,  3.65s/it]
Found a match. Car Number 1 | length nonzerox: 19600 | length nonzeroy: 19600
Bounding box: ((812, 378), (951, 531))




 31%|███       | 12/39 [00:44<01:38,  3.64s/it]
Found a match. Car Number 2 | length nonzerox: 11956 | length nonzeroy: 11956
Bounding box: ((420, 546), (531, 657))




 33%|███▎      | 13/39 [00:48<01:37,  3.74s/it]
Found a match. Car Number 1 | length nonzerox: 19796 | length nonzeroy: 19796
Bounding box: ((812, 378), (951, 531))
Found a match. Car Number 2 | length nonzerox: 12152 | length nonzeroy: 12152
Bounding box: ((420, 546), (531, 657))




 36%|███▌      | 14/39 [00:52<01:34,  3.77s/it]




 38%|███▊      | 15/39 [00:55<01:29,  3.72s/it]
Found a match. Car Number 1 | length nonzerox: 19992 | length nonzeroy: 19992
Bounding box: ((812, 378), (951, 531))




 41%|████      | 16/39 [00:59<01:24,  3.67s/it]
Found a match. Car Number 2 | length nonzerox: 19600 | length nonzeroy: 19600
Bounding box: ((812, 378), (951, 531))




 44%|████▎     | 17/39 [01:02<01:20,  3.64s/it]
Found a match. Car Number 2 | length nonzerox: 20384 | length nonzeroy: 20384
Bounding box: ((812, 378), (951, 531))




 46%|████▌     | 18/39 [01:06<01:16,  3.62s/it]
Found a match. Car Number 2 | length nonzerox: 19208 | length nonzeroy: 19208
Bounding box: ((812, 378), (951, 531))




 49%|████▊     | 19/39 [01:10<01:12,  3.61s/it]
Found a match. Car Number 2 | length nonzerox: 19796 | length nonzeroy: 19796
Bounding box: ((812, 378), (951, 531))
Found a match. Car Number 4 | length nonzerox: 9212 | length nonzeroy: 9212
Bounding box: ((420, 560), (517, 657))




 51%|█████▏    | 20/39 [01:13<01:07,  3.58s/it]




 54%|█████▍    | 21/39 [01:17<01:04,  3.57s/it]
Found a match. Car Number 2 | length nonzerox: 17052 | length nonzeroy: 17052
Bounding box: ((826, 392), (951, 531))




 56%|█████▋    | 22/39 [01:20<01:00,  3.57s/it]
Found a match. Car Number 3 | length nonzerox: 19992 | length nonzeroy: 19992
Bounding box: ((812, 378), (951, 531))




 59%|█████▉    | 23/39 [01:24<00:57,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 17052 | length nonzeroy: 17052
Bounding box: ((826, 392), (951, 531))




 62%|██████▏   | 24/39 [01:27<00:53,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 16856 | length nonzeroy: 16856
Bounding box: ((826, 392), (951, 531))




 64%|██████▍   | 25/39 [01:31<00:49,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 16660 | length nonzeroy: 16660
Bounding box: ((826, 392), (951, 531))




 67%|██████▋   | 26/39 [01:34<00:46,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 18032 | length nonzeroy: 18032
Bounding box: ((812, 392), (951, 531))




 69%|██████▉   | 27/39 [01:38<00:42,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 17836 | length nonzeroy: 17836
Bounding box: ((812, 392), (951, 531))




 72%|███████▏  | 28/39 [01:42<00:39,  3.56s/it]




 74%|███████▍  | 29/39 [01:45<00:35,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 18228 | length nonzeroy: 18228
Bounding box: ((812, 392), (951, 531))




 77%|███████▋  | 30/39 [01:49<00:32,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 16660 | length nonzeroy: 16660
Bounding box: ((826, 392), (951, 531))




 79%|███████▉  | 31/39 [01:52<00:28,  3.57s/it]




 82%|████████▏ | 32/39 [01:56<00:25,  3.63s/it]




 85%|████████▍ | 33/39 [02:00<00:22,  3.73s/it]
Found a match. Car Number 2 | length nonzerox: 19404 | length nonzeroy: 19404
Bounding box: ((812, 378), (951, 531))




 87%|████████▋ | 34/39 [02:04<00:18,  3.68s/it]
Found a match. Car Number 1 | length nonzerox: 13524 | length nonzeroy: 13524
Bounding box: ((742, 196), (853, 321))




 90%|████████▉ | 35/39 [02:07<00:14,  3.65s/it]
Found a match. Car Number 1 | length nonzerox: 19600 | length nonzeroy: 19600
Bounding box: ((812, 378), (951, 531))




 92%|█████████▏| 36/39 [02:11<00:10,  3.61s/it]




 95%|█████████▍| 37/39 [02:14<00:07,  3.60s/it]
Found a match. Car Number 1 | length nonzerox: 20776 | length nonzeroy: 20776
Bounding box: ((812, 378), (965, 531))




 97%|█████████▋| 38/39 [02:18<00:03,  3.59s/it]
Found a match. Car Number 1 | length nonzerox: 19992 | length nonzeroy: 19992
Bounding box: ((812, 378), (951, 531))




[MoviePy] Done.
[MoviePy] >>>> Video ready: data/test_output.mp4 

Out[ ]:
In [ ]:
project_ouput = 'project_output.mp4'
PROJECT_VIDEO = 'project_video.mp4'
VIDEO_FILE_PATH = os.path.join(WORKING_DIRECTORY, PROJECT_VIDEO)
VIDEO_OUTPUT_PATH = os.path.join(WORKING_DIRECTORY, project_ouput)

carslist = []
clip = VideoFileClip(VIDEO_FILE_PATH)
project_clip = clip.fl_image(process_image)
project_clip.write_videofile(VIDEO_OUTPUT_PATH, audio=False)
[MoviePy] >>>> Building video data/project_output.mp4
[MoviePy] Writing video data/project_output.mp4




  0%|          | 0/1261 [00:00<?, ?it/s]




  0%|          | 1/1261 [00:03<1:16:27,  3.64s/it]




  0%|          | 2/1261 [00:07<1:16:17,  3.64s/it]




  0%|          | 3/1261 [00:10<1:15:53,  3.62s/it]




  0%|          | 4/1261 [00:14<1:15:51,  3.62s/it]




  0%|          | 5/1261 [00:18<1:15:40,  3.62s/it]




  0%|          | 6/1261 [00:21<1:15:23,  3.60s/it]




  1%|          | 7/1261 [00:25<1:14:55,  3.59s/it]




  1%|          | 8/1261 [00:28<1:14:56,  3.59s/it]




  1%|          | 9/1261 [00:32<1:15:09,  3.60s/it]




  1%|          | 10/1261 [00:35<1:14:44,  3.59s/it]




  1%|          | 11/1261 [00:39<1:14:38,  3.58s/it]




  1%|          | 12/1261 [00:43<1:14:44,  3.59s/it]




  1%|          | 13/1261 [00:46<1:14:49,  3.60s/it]
Found a match. Car Number 1 | length nonzerox: 19600 | length nonzeroy: 19600
Bounding box: ((420, 462), (629, 671))




  1%|          | 14/1261 [00:50<1:14:35,  3.59s/it]




  1%|          | 15/1261 [00:53<1:14:18,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 24500 | length nonzeroy: 24500
Bounding box: ((406, 462), (629, 671))




  1%|▏         | 16/1261 [00:57<1:14:29,  3.59s/it]




  1%|▏         | 17/1261 [01:01<1:14:28,  3.59s/it]




  1%|▏         | 18/1261 [01:04<1:14:08,  3.58s/it]




  2%|▏         | 19/1261 [01:08<1:14:01,  3.58s/it]




  2%|▏         | 20/1261 [01:11<1:13:59,  3.58s/it]




  2%|▏         | 21/1261 [01:15<1:14:14,  3.59s/it]




  2%|▏         | 22/1261 [01:18<1:13:56,  3.58s/it]




  2%|▏         | 23/1261 [01:22<1:14:02,  3.59s/it]




  2%|▏         | 24/1261 [01:26<1:13:38,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 9996 | length nonzeroy: 9996
Bounding box: ((518, 462), (629, 559))




  2%|▏         | 25/1261 [01:29<1:13:31,  3.57s/it]




  2%|▏         | 26/1261 [01:33<1:13:15,  3.56s/it]




  2%|▏         | 27/1261 [01:36<1:13:04,  3.55s/it]




  2%|▏         | 28/1261 [01:40<1:12:54,  3.55s/it]




  2%|▏         | 29/1261 [01:43<1:12:43,  3.54s/it]




  2%|▏         | 30/1261 [01:47<1:12:25,  3.53s/it]




  2%|▏         | 31/1261 [01:50<1:12:14,  3.52s/it]




  3%|▎         | 32/1261 [01:54<1:12:28,  3.54s/it]




  3%|▎         | 33/1261 [01:57<1:12:24,  3.54s/it]
Found a match. Car Number 1 | length nonzerox: 35280 | length nonzeroy: 35280
Bounding box: ((392, 448), (643, 685))




  3%|▎         | 34/1261 [02:01<1:12:36,  3.55s/it]




  3%|▎         | 35/1261 [02:05<1:12:33,  3.55s/it]




  3%|▎         | 36/1261 [02:08<1:12:32,  3.55s/it]




  3%|▎         | 37/1261 [02:12<1:12:15,  3.54s/it]




  3%|▎         | 38/1261 [02:15<1:12:03,  3.54s/it]




  3%|▎         | 39/1261 [02:19<1:12:33,  3.56s/it]




  3%|▎         | 40/1261 [02:22<1:12:45,  3.58s/it]




  3%|▎         | 41/1261 [02:26<1:12:25,  3.56s/it]




  3%|▎         | 42/1261 [02:29<1:12:18,  3.56s/it]




  3%|▎         | 43/1261 [02:33<1:12:31,  3.57s/it]




  3%|▎         | 44/1261 [02:37<1:12:17,  3.56s/it]




  4%|▎         | 45/1261 [02:40<1:12:04,  3.56s/it]
Found a match. Car Number 3 | length nonzerox: 31360 | length nonzeroy: 31360
Bounding box: ((392, 448), (643, 685))




  4%|▎         | 46/1261 [02:44<1:12:10,  3.56s/it]




  4%|▎         | 47/1261 [02:47<1:12:36,  3.59s/it]
Found a match. Car Number 2 | length nonzerox: 36456 | length nonzeroy: 36456
Bounding box: ((392, 448), (643, 685))




  4%|▍         | 48/1261 [02:51<1:12:45,  3.60s/it]




  4%|▍         | 49/1261 [02:55<1:12:13,  3.58s/it]




  4%|▍         | 50/1261 [02:58<1:12:48,  3.61s/it]




  4%|▍         | 51/1261 [03:02<1:12:47,  3.61s/it]




  4%|▍         | 52/1261 [03:05<1:12:36,  3.60s/it]




  4%|▍         | 53/1261 [03:09<1:11:59,  3.58s/it]




  4%|▍         | 54/1261 [03:13<1:11:55,  3.58s/it]




  4%|▍         | 55/1261 [03:16<1:12:24,  3.60s/it]




  4%|▍         | 56/1261 [03:20<1:12:16,  3.60s/it]
Found a match. Car Number 1 | length nonzerox: 33124 | length nonzeroy: 33124
Bounding box: ((406, 448), (643, 671))




  5%|▍         | 57/1261 [03:23<1:11:57,  3.59s/it]




  5%|▍         | 58/1261 [03:27<1:11:44,  3.58s/it]




  5%|▍         | 59/1261 [03:30<1:11:45,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 28812 | length nonzeroy: 28812
Bounding box: ((392, 462), (629, 685))




  5%|▍         | 60/1261 [03:34<1:11:50,  3.59s/it]
Found a match. Car Number 1 | length nonzerox: 29792 | length nonzeroy: 29792
Bounding box: ((406, 448), (643, 671))




  5%|▍         | 61/1261 [03:38<1:11:41,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((532, 462), (629, 545))




  5%|▍         | 62/1261 [03:41<1:11:28,  3.58s/it]




  5%|▍         | 63/1261 [03:45<1:11:18,  3.57s/it]




  5%|▌         | 64/1261 [03:49<1:14:59,  3.76s/it]




  5%|▌         | 65/1261 [03:53<1:14:06,  3.72s/it]




  5%|▌         | 66/1261 [03:56<1:13:11,  3.67s/it]




  5%|▌         | 67/1261 [04:00<1:12:41,  3.65s/it]




  5%|▌         | 68/1261 [04:03<1:12:18,  3.64s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((532, 462), (629, 545))




  5%|▌         | 69/1261 [04:07<1:11:43,  3.61s/it]
Found a match. Car Number 1 | length nonzerox: 18228 | length nonzeroy: 18228
Bounding box: ((490, 462), (643, 601))




  6%|▌         | 70/1261 [04:11<1:11:34,  3.61s/it]




  6%|▌         | 71/1261 [04:14<1:11:42,  3.62s/it]




  6%|▌         | 72/1261 [04:18<1:11:22,  3.60s/it]




  6%|▌         | 73/1261 [04:21<1:11:11,  3.60s/it]




  6%|▌         | 74/1261 [04:25<1:10:51,  3.58s/it]




  6%|▌         | 75/1261 [04:28<1:10:45,  3.58s/it]




  6%|▌         | 76/1261 [04:32<1:10:45,  3.58s/it]




  6%|▌         | 77/1261 [04:36<1:10:22,  3.57s/it]




  6%|▌         | 78/1261 [04:39<1:10:06,  3.56s/it]




  6%|▋         | 79/1261 [04:43<1:10:07,  3.56s/it]




  6%|▋         | 80/1261 [04:46<1:10:02,  3.56s/it]




  6%|▋         | 81/1261 [04:50<1:09:43,  3.55s/it]




  7%|▋         | 82/1261 [04:53<1:10:02,  3.56s/it]




  7%|▋         | 83/1261 [04:57<1:10:00,  3.57s/it]




  7%|▋         | 84/1261 [05:00<1:09:58,  3.57s/it]




  7%|▋         | 85/1261 [05:04<1:09:43,  3.56s/it]




  7%|▋         | 86/1261 [05:08<1:09:45,  3.56s/it]




  7%|▋         | 87/1261 [05:11<1:09:41,  3.56s/it]




  7%|▋         | 88/1261 [05:15<1:09:26,  3.55s/it]
Found a match. Car Number 1 | length nonzerox: 11760 | length nonzeroy: 11760
Bounding box: ((532, 448), (643, 559))




  7%|▋         | 89/1261 [05:18<1:09:20,  3.55s/it]




  7%|▋         | 90/1261 [05:22<1:09:29,  3.56s/it]




  7%|▋         | 91/1261 [05:25<1:09:31,  3.57s/it]




  7%|▋         | 92/1261 [05:29<1:09:19,  3.56s/it]




  7%|▋         | 93/1261 [05:32<1:09:12,  3.56s/it]




  7%|▋         | 94/1261 [05:36<1:09:12,  3.56s/it]




  8%|▊         | 95/1261 [05:40<1:09:19,  3.57s/it]




  8%|▊         | 96/1261 [05:43<1:09:01,  3.55s/it]




  8%|▊         | 97/1261 [05:47<1:09:07,  3.56s/it]




  8%|▊         | 98/1261 [05:50<1:09:01,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 33908 | length nonzeroy: 33908
Bounding box: ((406, 434), (657, 671))




  8%|▊         | 99/1261 [05:54<1:09:05,  3.57s/it]




  8%|▊         | 100/1261 [05:57<1:08:46,  3.55s/it]




  8%|▊         | 101/1261 [06:01<1:08:53,  3.56s/it]




  8%|▊         | 102/1261 [06:05<1:08:45,  3.56s/it]




  8%|▊         | 103/1261 [06:08<1:08:44,  3.56s/it]




  8%|▊         | 104/1261 [06:12<1:08:25,  3.55s/it]




  8%|▊         | 105/1261 [06:15<1:08:24,  3.55s/it]




  8%|▊         | 106/1261 [06:19<1:08:15,  3.55s/it]




  8%|▊         | 107/1261 [06:22<1:08:17,  3.55s/it]




  9%|▊         | 108/1261 [06:26<1:08:01,  3.54s/it]




  9%|▊         | 109/1261 [06:29<1:08:10,  3.55s/it]




  9%|▊         | 110/1261 [06:33<1:08:09,  3.55s/it]




  9%|▉         | 111/1261 [06:36<1:08:05,  3.55s/it]
Found a match. Car Number 1 | length nonzerox: 28028 | length nonzeroy: 28028
Bounding box: ((392, 462), (629, 671))




  9%|▉         | 112/1261 [06:40<1:07:54,  3.55s/it]




  9%|▉         | 113/1261 [06:44<1:08:07,  3.56s/it]




  9%|▉         | 114/1261 [06:47<1:08:07,  3.56s/it]
Found a match. Car Number 2 | length nonzerox: 12740 | length nonzeroy: 12740
Bounding box: ((532, 448), (643, 573))




  9%|▉         | 115/1261 [06:51<1:08:12,  3.57s/it]




  9%|▉         | 116/1261 [06:54<1:08:04,  3.57s/it]




  9%|▉         | 117/1261 [06:58<1:08:01,  3.57s/it]




  9%|▉         | 118/1261 [07:01<1:07:58,  3.57s/it]




  9%|▉         | 119/1261 [07:05<1:07:44,  3.56s/it]
Found a match. Car Number 2 | length nonzerox: 32732 | length nonzeroy: 32732
Bounding box: ((392, 462), (629, 685))




 10%|▉         | 120/1261 [07:09<1:08:04,  3.58s/it]




 10%|▉         | 121/1261 [07:12<1:08:02,  3.58s/it]




 10%|▉         | 122/1261 [07:16<1:08:04,  3.59s/it]




 10%|▉         | 123/1261 [07:19<1:07:35,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 14112 | length nonzeroy: 14112
Bounding box: ((518, 448), (643, 573))




 10%|▉         | 124/1261 [07:23<1:07:37,  3.57s/it]




 10%|▉         | 125/1261 [07:26<1:07:34,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 35280 | length nonzeroy: 35280
Bounding box: ((392, 448), (643, 685))




 10%|▉         | 126/1261 [07:30<1:07:44,  3.58s/it]




 10%|█         | 127/1261 [07:34<1:08:17,  3.61s/it]




 10%|█         | 128/1261 [07:38<1:11:45,  3.80s/it]
Found a match. Car Number 1 | length nonzerox: 12152 | length nonzeroy: 12152
Bounding box: ((532, 448), (643, 559))




 10%|█         | 129/1261 [07:42<1:10:47,  3.75s/it]




 10%|█         | 130/1261 [07:45<1:09:40,  3.70s/it]




 10%|█         | 131/1261 [07:49<1:08:47,  3.65s/it]
Found a match. Car Number 1 | length nonzerox: 27440 | length nonzeroy: 27440
Bounding box: ((406, 448), (643, 671))




 10%|█         | 132/1261 [07:52<1:08:12,  3.63s/it]
Found a match. Car Number 1 | length nonzerox: 30968 | length nonzeroy: 30968
Bounding box: ((406, 448), (657, 671))




 11%|█         | 133/1261 [07:56<1:07:55,  3.61s/it]




 11%|█         | 134/1261 [07:59<1:07:32,  3.60s/it]




 11%|█         | 135/1261 [08:03<1:07:08,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 36260 | length nonzeroy: 36260
Bounding box: ((406, 434), (657, 671))




 11%|█         | 136/1261 [08:07<1:07:01,  3.58s/it]




 11%|█         | 137/1261 [08:10<1:06:51,  3.57s/it]




 11%|█         | 138/1261 [08:14<1:06:47,  3.57s/it]




 11%|█         | 139/1261 [08:17<1:06:46,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 28420 | length nonzeroy: 28420
Bounding box: ((420, 448), (643, 657))




 11%|█         | 140/1261 [08:21<1:06:46,  3.57s/it]




 11%|█         | 141/1261 [08:24<1:06:52,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 10584 | length nonzeroy: 10584
Bounding box: ((532, 448), (643, 559))




 11%|█▏        | 142/1261 [08:28<1:06:53,  3.59s/it]




 11%|█▏        | 143/1261 [08:32<1:06:49,  3.59s/it]




 11%|█▏        | 144/1261 [08:35<1:06:42,  3.58s/it]




 11%|█▏        | 145/1261 [08:39<1:06:39,  3.58s/it]




 12%|█▏        | 146/1261 [08:42<1:06:32,  3.58s/it]




 12%|█▏        | 147/1261 [08:46<1:06:19,  3.57s/it]




 12%|█▏        | 148/1261 [08:50<1:09:25,  3.74s/it]
Found a match. Car Number 2 | length nonzerox: 10584 | length nonzeroy: 10584
Bounding box: ((392, 574), (503, 671))




 12%|█▏        | 149/1261 [08:54<1:08:23,  3.69s/it]




 12%|█▏        | 150/1261 [08:57<1:07:29,  3.65s/it]




 12%|█▏        | 151/1261 [09:01<1:06:57,  3.62s/it]
Found a match. Car Number 2 | length nonzerox: 12152 | length nonzeroy: 12152
Bounding box: ((532, 448), (643, 559))




 12%|█▏        | 152/1261 [09:04<1:06:38,  3.61s/it]




 12%|█▏        | 153/1261 [09:08<1:06:18,  3.59s/it]




 12%|█▏        | 154/1261 [09:11<1:05:58,  3.58s/it]




 12%|█▏        | 155/1261 [09:15<1:05:46,  3.57s/it]




 12%|█▏        | 156/1261 [09:18<1:05:37,  3.56s/it]




 12%|█▏        | 157/1261 [09:22<1:05:37,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 24696 | length nonzeroy: 24696
Bounding box: ((406, 448), (629, 657))




 13%|█▎        | 158/1261 [09:26<1:05:36,  3.57s/it]




 13%|█▎        | 159/1261 [09:29<1:05:21,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 29792 | length nonzeroy: 29792
Bounding box: ((406, 448), (643, 671))




 13%|█▎        | 160/1261 [09:33<1:05:24,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 30380 | length nonzeroy: 30380
Bounding box: ((406, 448), (643, 671))




 13%|█▎        | 161/1261 [09:36<1:05:37,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 12152 | length nonzeroy: 12152
Bounding box: ((532, 448), (643, 559))




 13%|█▎        | 162/1261 [09:40<1:05:25,  3.57s/it]




 13%|█▎        | 163/1261 [09:43<1:05:00,  3.55s/it]




 13%|█▎        | 164/1261 [09:47<1:05:06,  3.56s/it]




 13%|█▎        | 165/1261 [09:51<1:05:07,  3.57s/it]




 13%|█▎        | 166/1261 [09:54<1:05:03,  3.56s/it]




 13%|█▎        | 167/1261 [09:58<1:04:45,  3.55s/it]




 13%|█▎        | 168/1261 [10:01<1:04:52,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 32536 | length nonzeroy: 32536
Bounding box: ((392, 448), (643, 685))




 13%|█▎        | 169/1261 [10:05<1:05:08,  3.58s/it]




 13%|█▎        | 170/1261 [10:08<1:04:59,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 24696 | length nonzeroy: 24696
Bounding box: ((392, 490), (587, 671))




 14%|█▎        | 171/1261 [10:12<1:04:41,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 18228 | length nonzeroy: 18228
Bounding box: ((392, 532), (545, 685))




 14%|█▎        | 172/1261 [10:16<1:04:45,  3.57s/it]




 14%|█▎        | 173/1261 [10:19<1:04:46,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 29400 | length nonzeroy: 29400
Bounding box: ((392, 462), (629, 671))




 14%|█▍        | 174/1261 [10:23<1:04:48,  3.58s/it]




 14%|█▍        | 175/1261 [10:26<1:04:35,  3.57s/it]




 14%|█▍        | 176/1261 [10:30<1:04:29,  3.57s/it]




 14%|█▍        | 177/1261 [10:33<1:04:27,  3.57s/it]




 14%|█▍        | 178/1261 [10:37<1:04:11,  3.56s/it]




 14%|█▍        | 179/1261 [10:40<1:04:08,  3.56s/it]




 14%|█▍        | 180/1261 [10:44<1:04:08,  3.56s/it]




 14%|█▍        | 181/1261 [10:48<1:04:04,  3.56s/it]




 14%|█▍        | 182/1261 [10:51<1:03:57,  3.56s/it]




 15%|█▍        | 183/1261 [10:55<1:03:36,  3.54s/it]




 15%|█▍        | 184/1261 [10:58<1:03:33,  3.54s/it]




 15%|█▍        | 185/1261 [11:02<1:03:31,  3.54s/it]




 15%|█▍        | 186/1261 [11:05<1:03:17,  3.53s/it]




 15%|█▍        | 187/1261 [11:09<1:03:29,  3.55s/it]




 15%|█▍        | 188/1261 [11:12<1:03:19,  3.54s/it]
Found a match. Car Number 1 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((1106, 406), (1203, 503))




 15%|█▍        | 189/1261 [11:16<1:03:30,  3.55s/it]




 15%|█▌        | 190/1261 [11:19<1:03:18,  3.55s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((1106, 406), (1189, 503))
Found a match. Car Number 2 | length nonzerox: 28420 | length nonzeroy: 28420
Bounding box: ((378, 462), (629, 685))




 15%|█▌        | 191/1261 [11:23<1:03:28,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((1106, 406), (1203, 503))
Found a match. Car Number 2 | length nonzerox: 22736 | length nonzeroy: 22736
Bounding box: ((406, 462), (629, 671))




 15%|█▌        | 192/1261 [11:27<1:03:36,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((1106, 406), (1189, 503))




 15%|█▌        | 193/1261 [11:30<1:03:45,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((1106, 406), (1189, 503))




 15%|█▌        | 194/1261 [11:34<1:03:25,  3.57s/it]




 15%|█▌        | 195/1261 [11:37<1:03:19,  3.56s/it]




 16%|█▌        | 196/1261 [11:41<1:03:19,  3.57s/it]




 16%|█▌        | 197/1261 [11:44<1:03:16,  3.57s/it]




 16%|█▌        | 198/1261 [11:48<1:03:02,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 31164 | length nonzeroy: 31164
Bounding box: ((392, 462), (629, 671))




 16%|█▌        | 199/1261 [11:52<1:03:05,  3.56s/it]




 16%|█▌        | 200/1261 [11:55<1:02:57,  3.56s/it]




 16%|█▌        | 201/1261 [11:59<1:02:44,  3.55s/it]
Found a match. Car Number 1 | length nonzerox: 17444 | length nonzeroy: 17444
Bounding box: ((476, 462), (615, 615))




 16%|█▌        | 202/1261 [12:02<1:02:45,  3.56s/it]




 16%|█▌        | 203/1261 [12:06<1:02:39,  3.55s/it]




 16%|█▌        | 204/1261 [12:09<1:02:31,  3.55s/it]




 16%|█▋        | 205/1261 [12:13<1:02:26,  3.55s/it]




 16%|█▋        | 206/1261 [12:16<1:02:21,  3.55s/it]




 16%|█▋        | 207/1261 [12:20<1:02:26,  3.55s/it]




 16%|█▋        | 208/1261 [12:24<1:02:26,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 8624 | length nonzeroy: 8624
Bounding box: ((1078, 406), (1175, 503))




 17%|█▋        | 209/1261 [12:27<1:02:16,  3.55s/it]
Found a match. Car Number 1 | length nonzerox: 27832 | length nonzeroy: 27832
Bounding box: ((392, 462), (629, 671))




 17%|█▋        | 210/1261 [12:31<1:02:23,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 35084 | length nonzeroy: 35084
Bounding box: ((378, 448), (629, 685))




 17%|█▋        | 211/1261 [12:34<1:02:20,  3.56s/it]




 17%|█▋        | 212/1261 [12:38<1:02:11,  3.56s/it]




 17%|█▋        | 213/1261 [12:41<1:02:07,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((1078, 406), (1175, 503))




 17%|█▋        | 214/1261 [12:45<1:02:12,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((1078, 406), (1175, 503))




 17%|█▋        | 215/1261 [12:49<1:02:12,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((1078, 406), (1175, 503))




 17%|█▋        | 216/1261 [12:52<1:02:17,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((1078, 406), (1175, 503))




 17%|█▋        | 217/1261 [12:56<1:02:00,  3.56s/it]




 17%|█▋        | 218/1261 [12:59<1:02:07,  3.57s/it]




 17%|█▋        | 219/1261 [13:03<1:02:02,  3.57s/it]




 17%|█▋        | 220/1261 [13:06<1:02:04,  3.58s/it]




 18%|█▊        | 221/1261 [13:10<1:01:42,  3.56s/it]




 18%|█▊        | 222/1261 [13:14<1:02:41,  3.62s/it]
Found a match. Car Number 2 | length nonzerox: 28812 | length nonzeroy: 28812
Bounding box: ((392, 476), (587, 685))




 18%|█▊        | 223/1261 [13:18<1:05:44,  3.80s/it]




 18%|█▊        | 224/1261 [13:22<1:04:51,  3.75s/it]
Found a match. Car Number 2 | length nonzerox: 14308 | length nonzeroy: 14308
Bounding box: ((378, 560), (503, 685))




 18%|█▊        | 225/1261 [13:25<1:03:42,  3.69s/it]




 18%|█▊        | 226/1261 [13:29<1:02:51,  3.64s/it]




 18%|█▊        | 227/1261 [13:32<1:02:23,  3.62s/it]




 18%|█▊        | 228/1261 [13:36<1:01:57,  3.60s/it]




 18%|█▊        | 229/1261 [13:39<1:01:32,  3.58s/it]




 18%|█▊        | 230/1261 [13:43<1:01:19,  3.57s/it]




 18%|█▊        | 231/1261 [13:46<1:01:10,  3.56s/it]




 18%|█▊        | 232/1261 [13:50<1:01:06,  3.56s/it]




 18%|█▊        | 233/1261 [13:53<1:00:53,  3.55s/it]




 19%|█▊        | 234/1261 [13:57<1:00:53,  3.56s/it]




 19%|█▊        | 235/1261 [14:01<1:00:48,  3.56s/it]




 19%|█▊        | 236/1261 [14:04<1:00:41,  3.55s/it]
Found a match. Car Number 1 | length nonzerox: 10192 | length nonzeroy: 10192
Bounding box: ((532, 448), (643, 559))




 19%|█▉        | 237/1261 [14:08<1:00:39,  3.55s/it]




 19%|█▉        | 238/1261 [14:11<1:00:29,  3.55s/it]




 19%|█▉        | 239/1261 [14:15<1:00:29,  3.55s/it]




 19%|█▉        | 240/1261 [14:18<1:00:24,  3.55s/it]




 19%|█▉        | 241/1261 [14:22<1:00:23,  3.55s/it]




 19%|█▉        | 242/1261 [14:25<1:00:22,  3.55s/it]




 19%|█▉        | 243/1261 [14:29<1:00:27,  3.56s/it]
Found a match. Car Number 3 | length nonzerox: 15680 | length nonzeroy: 15680
Bounding box: ((378, 532), (517, 671))




 19%|█▉        | 244/1261 [14:33<1:03:35,  3.75s/it]




 19%|█▉        | 245/1261 [14:37<1:02:32,  3.69s/it]
Found a match. Car Number 1 | length nonzerox: 12544 | length nonzeroy: 12544
Bounding box: ((1036, 392), (1147, 503))




 20%|█▉        | 246/1261 [14:40<1:01:52,  3.66s/it]
Found a match. Car Number 1 | length nonzerox: 10388 | length nonzeroy: 10388
Bounding box: ((1036, 392), (1147, 503))




 20%|█▉        | 247/1261 [14:44<1:01:39,  3.65s/it]




 20%|█▉        | 248/1261 [14:48<1:01:13,  3.63s/it]
Found a match. Car Number 1 | length nonzerox: 10584 | length nonzeroy: 10584
Bounding box: ((1050, 392), (1147, 503))




 20%|█▉        | 249/1261 [14:51<1:00:57,  3.61s/it]
Found a match. Car Number 1 | length nonzerox: 10584 | length nonzeroy: 10584
Bounding box: ((1050, 392), (1147, 503))




 20%|█▉        | 250/1261 [14:55<1:00:33,  3.59s/it]
Found a match. Car Number 1 | length nonzerox: 10584 | length nonzeroy: 10584
Bounding box: ((1050, 392), (1147, 503))




 20%|█▉        | 251/1261 [14:58<1:00:23,  3.59s/it]
Found a match. Car Number 1 | length nonzerox: 10584 | length nonzeroy: 10584
Bounding box: ((1050, 392), (1147, 503))




 20%|█▉        | 252/1261 [15:02<1:00:13,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 11956 | length nonzeroy: 11956
Bounding box: ((1036, 392), (1147, 503))




 20%|██        | 253/1261 [15:05<1:00:07,  3.58s/it]
Found a match. Car Number 3 | length nonzerox: 19600 | length nonzeroy: 19600
Bounding box: ((378, 532), (531, 671))




 20%|██        | 254/1261 [15:09<1:00:02,  3.58s/it]




 20%|██        | 255/1261 [15:13<59:56,  3.57s/it]  




 20%|██        | 256/1261 [15:16<59:40,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((406, 546), (503, 643))




 20%|██        | 257/1261 [15:20<59:34,  3.56s/it]




 20%|██        | 258/1261 [15:23<59:35,  3.56s/it]




 21%|██        | 259/1261 [15:27<59:31,  3.56s/it]




 21%|██        | 260/1261 [15:30<59:20,  3.56s/it]
Found a match. Car Number 2 | length nonzerox: 6076 | length nonzeroy: 6076
Bounding box: ((532, 462), (601, 559))




 21%|██        | 261/1261 [15:34<59:26,  3.57s/it]




 21%|██        | 262/1261 [15:37<59:29,  3.57s/it]




 21%|██        | 263/1261 [15:41<59:23,  3.57s/it]




 21%|██        | 264/1261 [15:45<59:09,  3.56s/it]




 21%|██        | 265/1261 [15:48<58:56,  3.55s/it]
Found a match. Car Number 1 | length nonzerox: 10388 | length nonzeroy: 10388
Bounding box: ((1036, 392), (1147, 503))




 21%|██        | 266/1261 [15:52<59:08,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 10388 | length nonzeroy: 10388
Bounding box: ((1036, 392), (1147, 503))




 21%|██        | 267/1261 [15:55<59:15,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 11368 | length nonzeroy: 11368
Bounding box: ((1036, 392), (1147, 503))
Found a match. Car Number 2 | length nonzerox: 11172 | length nonzeroy: 11172
Bounding box: ((392, 546), (503, 657))




 21%|██▏       | 268/1261 [15:59<59:11,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 9212 | length nonzeroy: 9212
Bounding box: ((1036, 392), (1147, 503))




 21%|██▏       | 269/1261 [16:02<59:14,  3.58s/it]




 21%|██▏       | 270/1261 [16:06<59:10,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 9016 | length nonzeroy: 9016
Bounding box: ((1036, 392), (1133, 503))




 21%|██▏       | 271/1261 [16:10<59:00,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 9996 | length nonzeroy: 9996
Bounding box: ((1036, 392), (1133, 503))




 22%|██▏       | 272/1261 [16:13<58:45,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 11172 | length nonzeroy: 11172
Bounding box: ((1036, 392), (1147, 503))




 22%|██▏       | 273/1261 [16:17<58:58,  3.58s/it]
Found a match. Car Number 2 | length nonzerox: 11956 | length nonzeroy: 11956
Bounding box: ((532, 434), (657, 559))
Found a match. Car Number 5 | length nonzerox: 12348 | length nonzeroy: 12348
Bounding box: ((392, 546), (503, 671))




 22%|██▏       | 274/1261 [16:20<58:50,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((1036, 406), (1133, 503))




 22%|██▏       | 275/1261 [16:24<58:45,  3.58s/it]




 22%|██▏       | 276/1261 [16:27<58:24,  3.56s/it]




 22%|██▏       | 277/1261 [16:31<58:20,  3.56s/it]
Found a match. Car Number 3 | length nonzerox: 12152 | length nonzeroy: 12152
Bounding box: ((392, 546), (503, 671))




 22%|██▏       | 278/1261 [16:35<58:28,  3.57s/it]




 22%|██▏       | 279/1261 [16:38<58:35,  3.58s/it]




 22%|██▏       | 280/1261 [16:42<58:18,  3.57s/it]
Found a match. Car Number 3 | length nonzerox: 15484 | length nonzeroy: 15484
Bounding box: ((364, 546), (503, 685))




 22%|██▏       | 281/1261 [16:45<58:22,  3.57s/it]




 22%|██▏       | 282/1261 [16:49<58:23,  3.58s/it]




 22%|██▏       | 283/1261 [16:53<58:27,  3.59s/it]
Found a match. Car Number 1 | length nonzerox: 3724 | length nonzeroy: 3724
Bounding box: ((1092, 406), (1133, 503))




 23%|██▎       | 284/1261 [16:56<58:15,  3.58s/it]




 23%|██▎       | 285/1261 [17:00<58:05,  3.57s/it]




 23%|██▎       | 286/1261 [17:03<57:54,  3.56s/it]




 23%|██▎       | 287/1261 [17:07<57:43,  3.56s/it]




 23%|██▎       | 288/1261 [17:10<57:31,  3.55s/it]




 23%|██▎       | 289/1261 [17:14<57:38,  3.56s/it]




 23%|██▎       | 290/1261 [17:17<57:28,  3.55s/it]




 23%|██▎       | 291/1261 [17:21<57:31,  3.56s/it]




 23%|██▎       | 292/1261 [17:24<57:22,  3.55s/it]




 23%|██▎       | 293/1261 [17:28<57:31,  3.57s/it]




 23%|██▎       | 294/1261 [17:32<57:23,  3.56s/it]




 23%|██▎       | 295/1261 [17:35<57:15,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((1022, 406), (1119, 489))




 23%|██▎       | 296/1261 [17:39<57:12,  3.56s/it]




 24%|██▎       | 297/1261 [17:42<57:10,  3.56s/it]




 24%|██▎       | 298/1261 [17:46<57:05,  3.56s/it]




 24%|██▎       | 299/1261 [17:49<56:40,  3.54s/it]




 24%|██▍       | 300/1261 [17:53<56:37,  3.54s/it]




 24%|██▍       | 301/1261 [17:56<56:41,  3.54s/it]




 24%|██▍       | 302/1261 [18:00<56:40,  3.55s/it]
Found a match. Car Number 1 | length nonzerox: 8820 | length nonzeroy: 8820
Bounding box: ((532, 462), (629, 559))




 24%|██▍       | 303/1261 [18:04<56:35,  3.54s/it]




 24%|██▍       | 304/1261 [18:07<56:29,  3.54s/it]




 24%|██▍       | 305/1261 [18:11<56:34,  3.55s/it]




 24%|██▍       | 306/1261 [18:14<56:28,  3.55s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((1008, 406), (1105, 489))




 24%|██▍       | 307/1261 [18:18<56:28,  3.55s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((1008, 406), (1105, 489))
Found a match. Car Number 2 | length nonzerox: 11956 | length nonzeroy: 11956
Bounding box: ((392, 560), (503, 671))




 24%|██▍       | 308/1261 [18:21<56:40,  3.57s/it]
Found a match. Car Number 2 | length nonzerox: 9408 | length nonzeroy: 9408
Bounding box: ((392, 574), (489, 671))




 25%|██▍       | 309/1261 [18:25<56:37,  3.57s/it]




 25%|██▍       | 310/1261 [18:28<56:33,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 5880 | length nonzeroy: 5880
Bounding box: ((1036, 406), (1105, 489))




 25%|██▍       | 311/1261 [18:32<56:36,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((1008, 406), (1105, 489))
Found a match. Car Number 2 | length nonzerox: 25284 | length nonzeroy: 25284
Bounding box: ((378, 476), (601, 671))




 25%|██▍       | 312/1261 [18:36<56:27,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((1008, 406), (1105, 489))




 25%|██▍       | 313/1261 [18:39<56:19,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((1008, 406), (1105, 489))




 25%|██▍       | 314/1261 [18:43<56:08,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((1008, 406), (1105, 489))




 25%|██▍       | 315/1261 [18:46<55:56,  3.55s/it]




 25%|██▌       | 316/1261 [18:50<58:51,  3.74s/it]
Found a match. Car Number 2 | length nonzerox: 28812 | length nonzeroy: 28812
Bounding box: ((392, 476), (601, 671))




 25%|██▌       | 317/1261 [18:54<58:05,  3.69s/it]




 25%|██▌       | 318/1261 [18:58<57:36,  3.67s/it]
Found a match. Car Number 1 | length nonzerox: 8820 | length nonzeroy: 8820
Bounding box: ((1022, 392), (1119, 489))




 25%|██▌       | 319/1261 [19:01<57:02,  3.63s/it]




 25%|██▌       | 320/1261 [19:05<56:41,  3.62s/it]
Found a match. Car Number 1 | length nonzerox: 3528 | length nonzeroy: 3528
Bounding box: ((1064, 406), (1105, 489))




 25%|██▌       | 321/1261 [19:08<56:28,  3.60s/it]
Found a match. Car Number 1 | length nonzerox: 3528 | length nonzeroy: 3528
Bounding box: ((1064, 406), (1105, 489))




 26%|██▌       | 322/1261 [19:12<56:25,  3.61s/it]
Found a match. Car Number 1 | length nonzerox: 3528 | length nonzeroy: 3528
Bounding box: ((1064, 406), (1105, 489))




 26%|██▌       | 323/1261 [19:15<56:09,  3.59s/it]




 26%|██▌       | 324/1261 [19:19<55:57,  3.58s/it]




 26%|██▌       | 325/1261 [19:23<55:51,  3.58s/it]




 26%|██▌       | 326/1261 [19:26<55:43,  3.58s/it]




 26%|██▌       | 327/1261 [19:30<55:29,  3.56s/it]
Found a match. Car Number 2 | length nonzerox: 11956 | length nonzeroy: 11956
Bounding box: ((406, 560), (517, 671))




 26%|██▌       | 328/1261 [19:33<55:27,  3.57s/it]




 26%|██▌       | 329/1261 [19:37<55:31,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 10780 | length nonzeroy: 10780
Bounding box: ((406, 546), (517, 657))




 26%|██▌       | 330/1261 [19:40<55:27,  3.57s/it]




 26%|██▌       | 331/1261 [19:44<55:06,  3.56s/it]




 26%|██▋       | 332/1261 [19:48<55:09,  3.56s/it]




 26%|██▋       | 333/1261 [19:51<55:11,  3.57s/it]




 26%|██▋       | 334/1261 [19:55<54:58,  3.56s/it]
Found a match. Car Number 1 | length nonzerox: 8820 | length nonzeroy: 8820
Bounding box: ((994, 406), (1091, 503))




 27%|██▋       | 335/1261 [19:58<55:00,  3.56s/it]
Found a match. Car Number 2 | length nonzerox: 10192 | length nonzeroy: 10192
Bounding box: ((518, 462), (629, 573))
Found a match. Car Number 3 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((392, 574), (489, 671))




 27%|██▋       | 336/1261 [20:02<54:59,  3.57s/it]




 27%|██▋       | 337/1261 [20:05<55:08,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 10584 | length nonzeroy: 10584
Bounding box: ((1008, 392), (1119, 503))
Found a match. Car Number 2 | length nonzerox: 1764 | length nonzeroy: 1764
Bounding box: ((602, 476), (643, 517))




 27%|██▋       | 338/1261 [20:09<55:00,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 10584 | length nonzeroy: 10584
Bounding box: ((1008, 392), (1119, 503))




 27%|██▋       | 339/1261 [20:13<55:07,  3.59s/it]
Found a match. Car Number 2 | length nonzerox: 24500 | length nonzeroy: 24500
Bounding box: ((392, 504), (587, 671))




 27%|██▋       | 340/1261 [20:16<55:03,  3.59s/it]




 27%|██▋       | 341/1261 [20:20<54:52,  3.58s/it]




 27%|██▋       | 342/1261 [20:23<54:50,  3.58s/it]
Found a match. Car Number 4 | length nonzerox: 10780 | length nonzeroy: 10780
Bounding box: ((420, 560), (531, 657))




 27%|██▋       | 343/1261 [20:27<54:54,  3.59s/it]




 27%|██▋       | 344/1261 [20:31<55:03,  3.60s/it]




 27%|██▋       | 345/1261 [20:34<54:51,  3.59s/it]




 27%|██▋       | 346/1261 [20:38<54:30,  3.57s/it]
Found a match. Car Number 2 | length nonzerox: 3528 | length nonzeroy: 3528
Bounding box: ((1036, 406), (1077, 489))




 28%|██▊       | 347/1261 [20:41<54:40,  3.59s/it]
Found a match. Car Number 1 | length nonzerox: 3528 | length nonzeroy: 3528
Bounding box: ((1036, 406), (1077, 489))




 28%|██▊       | 348/1261 [20:45<54:45,  3.60s/it]
Found a match. Car Number 1 | length nonzerox: 3528 | length nonzeroy: 3528
Bounding box: ((1036, 406), (1077, 489))




 28%|██▊       | 349/1261 [20:49<54:44,  3.60s/it]




 28%|██▊       | 350/1261 [20:52<54:18,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((1036, 392), (1147, 503))
Found a match. Car Number 3 | length nonzerox: 18228 | length nonzeroy: 18228
Bounding box: ((686, 532), (839, 657))




 28%|██▊       | 351/1261 [20:56<54:23,  3.59s/it]
Found a match. Car Number 1 | length nonzerox: 9212 | length nonzeroy: 9212
Bounding box: ((1036, 392), (1147, 503))




 28%|██▊       | 352/1261 [20:59<54:21,  3.59s/it]




 28%|██▊       | 353/1261 [21:03<54:17,  3.59s/it]




 28%|██▊       | 354/1261 [21:06<54:11,  3.58s/it]




 28%|██▊       | 355/1261 [21:10<54:02,  3.58s/it]




 28%|██▊       | 356/1261 [21:14<53:52,  3.57s/it]
Found a match. Car Number 2 | length nonzerox: 20776 | length nonzeroy: 20776
Bounding box: ((434, 504), (601, 657))




 28%|██▊       | 357/1261 [21:17<53:49,  3.57s/it]
Found a match. Car Number 3 | length nonzerox: 16268 | length nonzeroy: 16268
Bounding box: ((392, 546), (531, 671))




 28%|██▊       | 358/1261 [21:21<53:39,  3.57s/it]




 28%|██▊       | 359/1261 [21:24<53:42,  3.57s/it]




 29%|██▊       | 360/1261 [21:28<53:41,  3.58s/it]




 29%|██▊       | 361/1261 [21:31<53:44,  3.58s/it]




 29%|██▊       | 362/1261 [21:35<53:26,  3.57s/it]




 29%|██▉       | 363/1261 [21:39<53:16,  3.56s/it]
Found a match. Car Number 2 | length nonzerox: 24892 | length nonzeroy: 24892
Bounding box: ((406, 462), (629, 657))




 29%|██▉       | 364/1261 [21:42<53:15,  3.56s/it]




 29%|██▉       | 365/1261 [21:46<53:08,  3.56s/it]




 29%|██▉       | 366/1261 [21:49<52:58,  3.55s/it]




 29%|██▉       | 367/1261 [21:53<53:09,  3.57s/it]




 29%|██▉       | 368/1261 [21:56<53:02,  3.56s/it]




 29%|██▉       | 369/1261 [22:00<53:00,  3.57s/it]




 29%|██▉       | 370/1261 [22:03<52:50,  3.56s/it]




 29%|██▉       | 371/1261 [22:07<52:51,  3.56s/it]




 30%|██▉       | 372/1261 [22:11<52:47,  3.56s/it]




 30%|██▉       | 373/1261 [22:14<52:37,  3.56s/it]




 30%|██▉       | 374/1261 [22:18<52:31,  3.55s/it]
Found a match. Car Number 3 | length nonzerox: 9408 | length nonzeroy: 9408
Bounding box: ((420, 560), (517, 657))




 30%|██▉       | 375/1261 [22:21<52:43,  3.57s/it]
Found a match. Car Number 2 | length nonzerox: 12152 | length nonzeroy: 12152
Bounding box: ((420, 546), (531, 657))




 30%|██▉       | 376/1261 [22:25<52:44,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 10192 | length nonzeroy: 10192
Bounding box: ((1008, 392), (1119, 503))




 30%|██▉       | 377/1261 [22:28<52:36,  3.57s/it]




 30%|██▉       | 378/1261 [22:32<52:37,  3.58s/it]




 30%|███       | 379/1261 [22:36<52:25,  3.57s/it]




 30%|███       | 380/1261 [22:39<52:20,  3.57s/it]




 30%|███       | 381/1261 [22:43<52:17,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 11956 | length nonzeroy: 11956
Bounding box: ((420, 546), (531, 657))




 30%|███       | 382/1261 [22:46<52:17,  3.57s/it]




 30%|███       | 383/1261 [22:50<52:12,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((994, 406), (1091, 489))




 30%|███       | 384/1261 [22:53<52:08,  3.57s/it]




 31%|███       | 385/1261 [22:57<51:49,  3.55s/it]




 31%|███       | 386/1261 [23:00<51:49,  3.55s/it]




 31%|███       | 387/1261 [23:04<51:42,  3.55s/it]




 31%|███       | 388/1261 [23:08<51:40,  3.55s/it]




 31%|███       | 389/1261 [23:11<51:28,  3.54s/it]
Found a match. Car Number 3 | length nonzerox: 2352 | length nonzeroy: 2352
Bounding box: ((476, 546), (517, 601))




 31%|███       | 390/1261 [23:15<51:37,  3.56s/it]




 31%|███       | 391/1261 [23:18<51:32,  3.55s/it]
Found a match. Car Number 1 | length nonzerox: 10780 | length nonzeroy: 10780
Bounding box: ((1134, 364), (1231, 475))




 31%|███       | 392/1261 [23:22<51:33,  3.56s/it]
Found a match. Car Number 2 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((980, 406), (1091, 503))
Found a match. Car Number 3 | length nonzerox: 11760 | length nonzeroy: 11760
Bounding box: ((504, 476), (615, 587))




 31%|███       | 393/1261 [23:25<51:32,  3.56s/it]




 31%|███       | 394/1261 [23:29<51:33,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 10584 | length nonzeroy: 10584
Bounding box: ((420, 546), (531, 657))




 31%|███▏      | 395/1261 [23:33<51:46,  3.59s/it]
Found a match. Car Number 2 | length nonzerox: 8232 | length nonzeroy: 8232
Bounding box: ((980, 406), (1077, 489))




 31%|███▏      | 396/1261 [23:36<51:36,  3.58s/it]




 31%|███▏      | 397/1261 [23:40<51:29,  3.58s/it]




 32%|███▏      | 398/1261 [23:43<51:23,  3.57s/it]




 32%|███▏      | 399/1261 [23:47<52:25,  3.65s/it]




 32%|███▏      | 400/1261 [23:51<53:26,  3.72s/it]




 32%|███▏      | 401/1261 [23:55<52:36,  3.67s/it]




 32%|███▏      | 402/1261 [23:58<52:08,  3.64s/it]
Found a match. Car Number 2 | length nonzerox: 21168 | length nonzeroy: 21168
Bounding box: ((420, 476), (629, 643))




 32%|███▏      | 403/1261 [24:02<52:00,  3.64s/it]




 32%|███▏      | 404/1261 [24:05<51:38,  3.62s/it]
Found a match. Car Number 1 | length nonzerox: 6076 | length nonzeroy: 6076
Bounding box: ((1148, 364), (1231, 447))
Found a match. Car Number 2 | length nonzerox: 12936 | length nonzeroy: 12936
Bounding box: ((504, 462), (629, 587))




 32%|███▏      | 405/1261 [24:09<51:17,  3.59s/it]




 32%|███▏      | 406/1261 [24:12<51:04,  3.58s/it]




 32%|███▏      | 407/1261 [24:16<50:53,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 19404 | length nonzeroy: 19404
Bounding box: ((406, 476), (601, 657))




 32%|███▏      | 408/1261 [24:20<50:48,  3.57s/it]




 32%|███▏      | 409/1261 [24:23<50:34,  3.56s/it]




 33%|███▎      | 410/1261 [24:27<50:29,  3.56s/it]




 33%|███▎      | 411/1261 [24:30<51:16,  3.62s/it]




 33%|███▎      | 412/1261 [24:37<1:02:11,  4.39s/it]




 33%|███▎      | 413/1261 [24:43<1:09:37,  4.93s/it]




 33%|███▎      | 414/1261 [24:47<1:05:31,  4.64s/it]




 33%|███▎      | 415/1261 [24:51<1:02:20,  4.42s/it]




 33%|███▎      | 416/1261 [24:54<59:15,  4.21s/it]  
Found a match. Car Number 1 | length nonzerox: 11368 | length nonzeroy: 11368
Bounding box: ((476, 490), (587, 601))




 33%|███▎      | 417/1261 [24:58<57:25,  4.08s/it]




 33%|███▎      | 418/1261 [25:02<55:38,  3.96s/it]




 33%|███▎      | 419/1261 [25:05<54:15,  3.87s/it]
Found a match. Car Number 1 | length nonzerox: 14112 | length nonzeroy: 14112
Bounding box: ((448, 504), (573, 643))




 33%|███▎      | 420/1261 [25:12<1:05:07,  4.65s/it]




 33%|███▎      | 421/1261 [25:18<1:10:45,  5.05s/it]




 33%|███▎      | 422/1261 [25:22<1:04:27,  4.61s/it]
Found a match. Car Number 2 | length nonzerox: 14896 | length nonzeroy: 14896
Bounding box: ((448, 504), (573, 643))




 34%|███▎      | 423/1261 [25:25<1:00:04,  4.30s/it]




 34%|███▎      | 424/1261 [25:29<56:57,  4.08s/it]  




 34%|███▎      | 425/1261 [25:32<54:43,  3.93s/it]
Found a match. Car Number 1 | length nonzerox: 9212 | length nonzeroy: 9212
Bounding box: ((952, 378), (1049, 475))




 34%|███▍      | 426/1261 [25:36<53:09,  3.82s/it]
Found a match. Car Number 5 | length nonzerox: 26852 | length nonzeroy: 26852
Bounding box: ((392, 504), (587, 685))




 34%|███▍      | 427/1261 [25:40<52:48,  3.80s/it]
Found a match. Car Number 3 | length nonzerox: 28812 | length nonzeroy: 28812
Bounding box: ((406, 476), (615, 671))




 34%|███▍      | 428/1261 [25:43<52:06,  3.75s/it]
Found a match. Car Number 2 | length nonzerox: 8820 | length nonzeroy: 8820
Bounding box: ((952, 378), (1049, 475))




 34%|███▍      | 429/1261 [25:47<51:25,  3.71s/it]




 34%|███▍      | 430/1261 [25:50<50:40,  3.66s/it]
Found a match. Car Number 2 | length nonzerox: 26264 | length nonzeroy: 26264
Bounding box: ((392, 504), (587, 671))




 34%|███▍      | 431/1261 [25:54<50:33,  3.66s/it]




 34%|███▍      | 432/1261 [25:58<50:11,  3.63s/it]




 34%|███▍      | 433/1261 [26:01<49:58,  3.62s/it]
Found a match. Car Number 1 | length nonzerox: 11956 | length nonzeroy: 11956
Bounding box: ((1134, 364), (1245, 475))




 34%|███▍      | 434/1261 [26:05<49:50,  3.62s/it]
Found a match. Car Number 2 | length nonzerox: 10976 | length nonzeroy: 10976
Bounding box: ((1134, 378), (1245, 475))




 34%|███▍      | 435/1261 [26:08<49:41,  3.61s/it]
Found a match. Car Number 1 | length nonzerox: 26460 | length nonzeroy: 26460
Bounding box: ((392, 490), (587, 671))




 35%|███▍      | 436/1261 [26:12<49:39,  3.61s/it]




 35%|███▍      | 437/1261 [26:16<49:27,  3.60s/it]
Found a match. Car Number 3 | length nonzerox: 10780 | length nonzeroy: 10780
Bounding box: ((658, 546), (769, 643))




 35%|███▍      | 438/1261 [26:19<49:05,  3.58s/it]
Found a match. Car Number 1 | length nonzerox: 24108 | length nonzeroy: 24108
Bounding box: ((406, 490), (587, 671))




 35%|███▍      | 439/1261 [26:23<49:10,  3.59s/it]
Found a match. Car Number 1 | length nonzerox: 27244 | length nonzeroy: 27244
Bounding box: ((392, 490), (587, 671))




 35%|███▍      | 440/1261 [26:26<49:02,  3.58s/it]




 35%|███▍      | 441/1261 [26:30<48:57,  3.58s/it]




 35%|███▌      | 442/1261 [26:33<48:38,  3.56s/it]




 35%|███▌      | 443/1261 [26:37<48:32,  3.56s/it]




 35%|███▌      | 444/1261 [26:40<48:32,  3.56s/it]




 35%|███▌      | 445/1261 [26:44<48:32,  3.57s/it]




 35%|███▌      | 446/1261 [26:48<48:24,  3.56s/it]




 35%|███▌      | 447/1261 [26:51<48:27,  3.57s/it]
Found a match. Car Number 1 | length nonzerox: 21560 | length nonzeroy: 21560
Bounding box: ((364, 532), (531, 685))




 36%|███▌      | 448/1261 [26:55<50:21,  3.72s/it]




 36%|███▌      | 449/1261 [27:00<55:11,  4.08s/it]




 36%|███▌      | 450/1261 [27:04<53:26,  3.95s/it]
Found a match. Car Number 2 | length nonzerox: 5488 | length nonzeroy: 5488
Bounding box: ((532, 490), (629, 601))




 36%|███▌      | 451/1261 [27:08<52:14,  3.87s/it]




 36%|███▌      | 452/1261 [27:12<56:21,  4.18s/it]




 36%|███▌      | 453/1261 [27:19<1:06:44,  4.96s/it]
Found a match. Car Number 5 | length nonzerox: 11760 | length nonzeroy: 11760
Bounding box: ((714, 518), (825, 629))




 36%|███▌      | 454/1261 [27:27<1:19:32,  5.91s/it]




 36%|███▌      | 455/1261 [27:31<1:11:11,  5.30s/it]




 36%|███▌      | 456/1261 [27:35<1:04:33,  4.81s/it]




 36%|███▌      | 457/1261 [27:39<1:00:15,  4.50s/it]




 36%|███▋      | 458/1261 [27:42<56:45,  4.24s/it]  




 36%|███▋      | 459/1261 [27:46<54:34,  4.08s/it]
Found a match. Car Number 2 | length nonzerox: 23324 | length nonzeroy: 23324
Bounding box: ((392, 504), (573, 671))




 36%|███▋      | 460/1261 [27:50<52:54,  3.96s/it]
Found a match. Car Number 1 | length nonzerox: 28812 | length nonzeroy: 28812
Bounding box: ((392, 490), (601, 671))




 37%|███▋      | 461/1261 [27:53<51:52,  3.89s/it]
Found a match. Car Number 1 | length nonzerox: 22736 | length nonzeroy: 22736
Bounding box: ((392, 504), (573, 671))




 37%|███▋      | 462/1261 [27:57<50:57,  3.83s/it]




 37%|███▋      | 463/1261 [28:01<50:02,  3.76s/it]
Found a match. Car Number 2 | length nonzerox: 11564 | length nonzeroy: 11564
Bounding box: ((392, 546), (503, 657))




 37%|███▋      | 464/1261 [28:04<49:22,  3.72s/it]




 37%|███▋      | 465/1261 [28:08<49:05,  3.70s/it]




 37%|███▋      | 466/1261 [28:12<48:53,  3.69s/it]
Found a match. Car Number 3 | length nonzerox: 11368 | length nonzeroy: 11368
Bounding box: ((392, 546), (503, 657))




 37%|███▋      | 467/1261 [28:15<48:23,  3.66s/it]




 37%|███▋      | 468/1261 [28:19<47:49,  3.62s/it]
Found a match. Car Number 2 | length nonzerox: 11564 | length nonzeroy: 11564
Bounding box: ((392, 546), (503, 657))




 37%|███▋      | 469/1261 [28:22<47:43,  3.62s/it]




 37%|███▋      | 470/1261 [28:26<47:39,  3.62s/it]




 37%|███▋      | 471/1261 [28:30<47:30,  3.61s/it]




 37%|███▋      | 472/1261 [28:33<47:14,  3.59s/it]




 38%|███▊      | 473/1261 [28:37<47:11,  3.59s/it]




 38%|███▊      | 474/1261 [28:40<47:10,  3.60s/it]




 38%|███▊      | 475/1261 [28:44<46:57,  3.58s/it]
Found a match. Car Number 3 | length nonzerox: 13132 | length nonzeroy: 13132
Bounding box: ((364, 560), (489, 685))




 38%|███▊      | 476/1261 [28:47<46:49,  3.58s/it]
Found a match. Car Number 5 | length nonzerox: 12152 | length nonzeroy: 12152
Bounding box: ((378, 560), (489, 671))




 38%|███▊      | 477/1261 [28:51<47:01,  3.60s/it]




 38%|███▊      | 478/1261 [28:55<47:01,  3.60s/it]




 38%|███▊      | 479/1261 [28:58<46:44,  3.59s/it]
Found a match. Car Number 1 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((924, 378), (1021, 475))




 38%|███▊      | 480/1261 [29:02<46:36,  3.58s/it]




 38%|███▊      | 481/1261 [29:05<46:39,  3.59s/it]




 38%|███▊      | 482/1261 [29:09<46:37,  3.59s/it]




 38%|███▊      | 483/1261 [29:13<46:28,  3.58s/it]




 38%|███▊      | 484/1261 [29:16<46:52,  3.62s/it]




 38%|███▊      | 485/1261 [29:20<46:45,  3.62s/it]




 39%|███▊      | 486/1261 [29:23<46:38,  3.61s/it]
Found a match. Car Number 1 | length nonzerox: 10976 | length nonzeroy: 10976
Bounding box: ((602, 504), (713, 615))




 39%|███▊      | 487/1261 [29:27<46:24,  3.60s/it]




 39%|███▊      | 488/1261 [29:31<46:21,  3.60s/it]




 39%|███▉      | 489/1261 [29:35<48:52,  3.80s/it]




 39%|███▉      | 490/1261 [29:39<48:18,  3.76s/it]




 39%|███▉      | 491/1261 [29:42<47:49,  3.73s/it]
Found a match. Car Number 1 | length nonzerox: 30772 | length nonzeroy: 30772
Bounding box: ((392, 476), (629, 671))




 39%|███▉      | 492/1261 [29:46<47:28,  3.70s/it]




 39%|███▉      | 493/1261 [29:50<47:08,  3.68s/it]
Found a match. Car Number 2 | length nonzerox: 11564 | length nonzeroy: 11564
Bounding box: ((504, 462), (629, 587))




 39%|███▉      | 494/1261 [29:53<47:22,  3.71s/it]




 39%|███▉      | 495/1261 [29:57<48:09,  3.77s/it]
Found a match. Car Number 1 | length nonzerox: 29596 | length nonzeroy: 29596
Bounding box: ((392, 476), (615, 657))




 39%|███▉      | 496/1261 [30:01<48:27,  3.80s/it]




 39%|███▉      | 497/1261 [30:05<48:34,  3.81s/it]




 39%|███▉      | 498/1261 [30:09<48:32,  3.82s/it]




 40%|███▉      | 499/1261 [30:13<48:40,  3.83s/it]




 40%|███▉      | 500/1261 [30:16<48:42,  3.84s/it]




 40%|███▉      | 501/1261 [30:20<48:41,  3.84s/it]
Found a match. Car Number 1 | length nonzerox: 8624 | length nonzeroy: 8624
Bounding box: ((532, 448), (629, 559))




 40%|███▉      | 502/1261 [30:24<48:47,  3.86s/it]
Found a match. Car Number 2 | length nonzerox: 12152 | length nonzeroy: 12152
Bounding box: ((392, 546), (503, 657))




 40%|███▉      | 503/1261 [30:28<50:18,  3.98s/it]




 40%|███▉      | 504/1261 [30:34<54:34,  4.33s/it]
Found a match. Car Number 1 | length nonzerox: 32732 | length nonzeroy: 32732
Bounding box: ((392, 434), (657, 657))




 40%|████      | 505/1261 [30:39<57:03,  4.53s/it]
Found a match. Car Number 1 | length nonzerox: 9408 | length nonzeroy: 9408
Bounding box: ((504, 462), (615, 573))




 40%|████      | 506/1261 [30:43<55:43,  4.43s/it]




 40%|████      | 507/1261 [30:47<54:45,  4.36s/it]




 40%|████      | 508/1261 [30:51<54:12,  4.32s/it]




 40%|████      | 509/1261 [30:56<56:55,  4.54s/it]




 40%|████      | 510/1261 [31:01<56:00,  4.47s/it]
Found a match. Car Number 2 | length nonzerox: 11956 | length nonzeroy: 11956
Bounding box: ((378, 560), (489, 671))




 41%|████      | 511/1261 [31:05<57:08,  4.57s/it]




 41%|████      | 512/1261 [31:10<56:06,  4.49s/it]
Found a match. Car Number 1 | length nonzerox: 9212 | length nonzeroy: 9212
Bounding box: ((910, 378), (1007, 475))




 41%|████      | 513/1261 [31:14<54:58,  4.41s/it]




 41%|████      | 514/1261 [31:18<53:56,  4.33s/it]
Found a match. Car Number 2 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((910, 378), (1007, 475))




 41%|████      | 515/1261 [31:22<53:08,  4.27s/it]
Found a match. Car Number 3 | length nonzerox: 29792 | length nonzeroy: 29792
Bounding box: ((378, 490), (601, 671))




 41%|████      | 516/1261 [31:26<52:38,  4.24s/it]
Found a match. Car Number 1 | length nonzerox: 5880 | length nonzeroy: 5880
Bounding box: ((420, 84), (489, 167))




 41%|████      | 517/1261 [31:31<52:32,  4.24s/it]




 41%|████      | 518/1261 [31:35<52:04,  4.21s/it]
Found a match. Car Number 1 | length nonzerox: 22932 | length nonzeroy: 22932
Bounding box: ((420, 490), (601, 657))




 41%|████      | 519/1261 [31:40<55:51,  4.52s/it]




 41%|████      | 520/1261 [31:45<57:02,  4.62s/it]




 41%|████▏     | 521/1261 [31:50<59:05,  4.79s/it]




 41%|████▏     | 522/1261 [31:56<1:02:15,  5.06s/it]
Found a match. Car Number 3 | length nonzerox: 9604 | length nonzeroy: 9604
Bounding box: ((700, 546), (797, 643))

In [ ]:
HTML("""
<video width="960" height="540" controls>
    <source src="{0}">
</video>
""".format(VIDEO_OUTPUT_PATH))
In [36]:
# # Add vehicle smoothing between frames

# carslist = []
# carslist.append(Vehicle())
# # Take the length of the least to know how many have been detected